自定义RatingBar(自定义view的实践)

本文介绍了一个自定义的RatingBar组件,解决了默认RatingBar组件星星大小不可调整的问题。通过自定义View绘制星星,并实现了点击反馈及大小自定义等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天看了看原生的Ratingbar,太丑了因此就搜了一大堆网上的自定义Ratingbar,我去网上的东西太不靠谱了。网上是这样写的:

drawable:

<?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+android:id/background"
        android:drawable="@drawable/star1"></item> <span></span>              
                <item android:id="@+android:id/secondaryProgress"
                android:drawable="@drawable/star1"></item>
                <item android:id="@+android:id/progress"
        android:drawable="@drawable/star2"></item>
</layer-list>


styles:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="roomRatingBar" parent="@android:style/Widget.RatingBar">
        <item name="android:progressDrawable">@drawable/room_rating_bar</item>
        <item name="android:minHeight">25dip</item>
        <item name="android:maxHeight">25dip</item>
    </style>

</resources>

然后在布局中使用:

<RatingBar
        android:id="@+id/room_ratingbar"
        style="@style/roomRatingBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
          android:numStars="5"
         android:rating="4"
        android:layout_marginLeft="10dp" >
    </RatingBar>

可是我改变不了每一个星星的大小啊,坑啊。其中的minHeight maxHeight 根本就不会控制每一个星星的大小他控制的是整体view的大小。那我就只能自定义一view了。搞起

package com.lidongdong.customratingbar;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * 类名:CustomRatingBar.java <br>
 * 描述: 自定义ratingbar<br>
 * 创建者:lidongdong <br>
 * 创建日期:2015-10-23下午1:11:18 <br>
 * 版本: <br>
 * 修改者:<br>
 * 修改日期:<br>
 */
public class CustomRatingBar extends View {

	private Context mContext;

	private Bitmap mNormalBitmap;
	private Bitmap mSelectedBitmap;

	private int starWidth = 45;
	private int starHeight = 45;

	private int starsMargin = 10;

	private Paint mPaint;

	private int starCount = 5;

	private int mWidth;
	private int mHeight;


	private int currentStarPos = -1;
	
	private OnStarClickListener onStarClickListener;
	
	private boolean isIndicator = false;
	

	
	public boolean isIndicator() {
		return isIndicator;
	}

	public void setIndicator(boolean isIndicator) {
		this.isIndicator = isIndicator;
	}

	public OnStarClickListener getOnStarClickListener() {
		return onStarClickListener;
	}

	public void setOnStarClickListener(OnStarClickListener onStarClickListener) {
		this.onStarClickListener = onStarClickListener;
	}

	public interface OnStarClickListener{
		
		void starClick(int pos);
	}


	private GestureDetector mGestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {

		@Override
		public boolean onSingleTapUp(MotionEvent event) {

			float x = event.getX();
			currentStarPos = (int) (x/(starsMargin + starWidth));
			
			if(onStarClickListener != null){
				
				onStarClickListener.starClick(currentStarPos+1);
			}
			
			invalidate();
			return false;
		}

		@Override
		public void onShowPress(MotionEvent e) {

		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
				float distanceY) {
			return false;
		}

		@Override
		public void onLongPress(MotionEvent e) {

		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			return false;
		}

		@Override
		public boolean onDown(MotionEvent e) {
			return false;
		}
	});


	public CustomRatingBar(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initData(context);

	}

	public CustomRatingBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		initData(context);
	}

	public CustomRatingBar(Context context) {
		super(context);
		initData(context);
	}

	public static Bitmap getBitmapFromDrawable(
			BitmapDrawable paramBitmapDrawable) {
		return paramBitmapDrawable.getBitmap();
	}

	private void initData(Context context) {

		this.mContext = context;

		this.mNormalBitmap = getBitmapFromDrawable((BitmapDrawable) this.mContext
				.getResources().getDrawable(R.mipmap.room_unselect));

		this.mSelectedBitmap = getBitmapFromDrawable((BitmapDrawable) this.mContext
				.getResources().getDrawable(R.mipmap.room_select));

		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setColor(Color.GRAY);
		mPaint.setStyle(Paint.Style.FILL);

	}


	@Override  
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
	{  
		int specMode = MeasureSpec.getMode(widthMeasureSpec);  
		int specSize = MeasureSpec.getSize(widthMeasureSpec);  

		if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate  
		{  
			mWidth = specSize;  
		} else  
		{  

			if (specMode == MeasureSpec.AT_MOST)// wrap_content  
			{  
				mWidth =  starCount * starWidth + (starCount - 1)* starsMargin;
			}  
		}  


		specMode = MeasureSpec.getMode(heightMeasureSpec);  
		specSize = MeasureSpec.getSize(heightMeasureSpec);  
		if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate  
		{  
			mHeight = specSize;  
		} else  
		{  
			if (specMode == MeasureSpec.AT_MOST)// wrap_content  
			{  
				mHeight = starHeight;  
			}  
		}  
		setMeasuredDimension(mWidth, mHeight);  

	}  

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		for (int i = 0; i < starCount; i++) {

			int left = i*(starWidth+starsMargin);
			int top = 0;
			int right = left + starWidth;
			int bottom = top + starHeight;

			canvas.drawBitmap(mNormalBitmap, null, new Rect(left, top,right, bottom), mPaint);


		}


		//		int selectLeft = 0;
		//		int selectTop = 0;
		//		int selectRight = starWidth/2;
		//		int selectBottom = starHeight;
		//
		//		Rect selectRect = new Rect(selectLeft, selectTop,selectRight,selectBottom);
		//
		//		Bitmap bp = Bitmap.createBitmap(mSelectedBitmap,0,0,mSelectedBitmap.getWidth()/2,mSelectedBitmap.getHeight());
		//
		//		canvas.drawBitmap(bp, null,selectRect, mPaint);

		if(currentStarPos != -1){

			for (int i = 0; i < currentStarPos + 1; i++) {


				int left = i*(starWidth+starsMargin);
				int top = 0;
				int right = left + starWidth;
				int bottom = top + starHeight;

				canvas.drawBitmap(mSelectedBitmap, null, new Rect(left, top,right, bottom), mPaint);

			}

		}

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {


		if (event.getPointerCount() == 1  && !isIndicator) {

			mGestureDetector.onTouchEvent(event);
		} 
		return true;

	}

}


如何使用呢?

main_activity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.sea.testRatingBar.CustomRatingBar
        android:id="@+id/room_ratingbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:background="@android:color/white" >
    </com.sea.testRatingBar.CustomRatingBar>

</LinearLayout>

MainActivity.java:

package com.sea.testRatingBar;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.sea.testRatingBar.CustomRatingBar.OnStarClickListener;

/**
 * 类名:testRatingBar.java <br>
 * 描述: <br>
 * 创建者:lidongdong <br>
 * 创建日期:2015-10-23下午1:10:42 <br>
 * 版本: <br>
 * 修改者:<br>
 * 修改日期:<br>
 */
public class MainActivity extends Activity {
	
	private CustomRatingBar crb;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        crb = (CustomRatingBar) findViewById(R.id.room_ratingbar);
        
        crb.setOnStarClickListener(new OnStarClickListener() {
			
			@Override
			public void starClick(int pos) {
				
				Log.i("DD",pos+"");
				
			}
		});
    }
}
效果图:


本代码已经托管到了github,github地址:

https://github.com/AndroidMyDream/CustomRatingBar



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值