自定义RatingBar
来源:互联网 发布:淘宝拉夏贝尔代购 编辑:程序博客网 时间:2024/05/22 01:48
RatingBar是基于SeekBar和ProgressBar的扩展,用星型来显示等级评定。使用RatingBar的默认大小时,用户可以触摸/拖动或使用键来设置评分,它有两种样式(小风格用ratingBarStyleSmall,大风格用ratingBarStyleIndicator),其中大的只适合指示,不适合于用户交互。使用过RatingBar的人都知道谷歌提供的这个控件有点过于古板了,自己定义的图片只能半个或者一个显示,并不能达到如4.1个的效果(可能是本人研究不够深入),下面是我自己定义的RatingBar,可以自己定义属性,设置星星图片,间距等。如下图
至于其他的功能嘛,是尽量跟着原生的RatingBar来写的,下面是自定义的代码:
public class HaisRatingBar extends View { /** * 正常的 */ private static final int NORMAL = 0; /** * 小型的 */ private static final int SAMLL = 1; /** * 背景图片 */ private Bitmap backgroundImg; /** * 显示点亮的星星 */ private Bitmap starLightImg; /** * 星星总数 */ private int starNums = 6; /** * 选中的数量 */ private float rating = 0; /** * 每个星星间隔距离 * 单位:px */ private int space; /** * 是否只是指示器 */ private boolean mIndicator; /** * 类型(即大图还是小图) */ private int type; /** * 背景图片宽度 */ private int bgWidth; /** * 背景图片高度 */ private int bgHeight; /** * 绘制 X方向的开始位置 */ private int drawStartX; public interface OnRatingBarChangeListener { void onRatingChanged(HaisRatingBar ratingBar, float rating, boolean fromUser); } private OnRatingBarChangeListener mOnRatingBarChangeListener; public HaisRatingBar(Context context) { this(context, null); } public HaisRatingBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public HaisRatingBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HaisRatingBar, defStyleAttr, 0); final boolean indicator = a.getBoolean(R.styleable.HaisRatingBar_indicator, false); final float rating = a.getFloat(R.styleable.HaisRatingBar_rating, 0); final int type = a.getInt(R.styleable.HaisRatingBar_type, NORMAL); final int statNums = a.getInt(R.styleable.HaisRatingBar_numStars, 5); final int space = a.getInt(R.styleable.HaisRatingBar_starSpace, 3); final int background = a.getResourceId(R.styleable.HaisRatingBar_starBackground, 0); final int startLight = a.getResourceId(R.styleable.HaisRatingBar_starLight, 0); a.recycle(); //初始化数据 setIndicator(indicator); setRating(rating); setType(type); setStarNums(statNums); setSpace(dpToPx(context, space)); Resources res = getResources(); if (background != 0 && startLight != 0) {//为了防止出现不良效果,背景和指示星星需要一起设置才起作用.否则使用默认 this.backgroundImg = BitmapFactory.decodeResource(res, background); this.starLightImg = BitmapFactory.decodeResource(res, startLight); } else { init(res); } bgWidth = backgroundImg.getWidth(); bgHeight = backgroundImg.getHeight(); } private void init(Resources res) { //设置资源图片 if (type == SAMLL) { backgroundImg = BitmapFactory.decodeResource(res, R.drawable.star_samll_darkl); starLightImg = BitmapFactory.decodeResource(res, R.drawable.star_small_light); } else { backgroundImg = BitmapFactory.decodeResource(res, R.drawable.star_normal_dark); starLightImg = BitmapFactory.decodeResource(res, R.drawable.star_normal_light); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (backgroundImg != null) { final int width = (bgWidth + space) * starNums; final int height = bgHeight; int w = resolveSizeAndState(width, widthMeasureSpec, 0); int h = resolveSizeAndState(height, heightMeasureSpec, 0); setMeasuredDimension(w, h); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i < starNums; i++) { float remainNums = rating - i; //每个星星开始绘制的位置 drawStartX = (bgWidth + space) * i; if ((i + 1) < rating) {//当前画的星星是否在被选中的范围内,在则画亮的星星 canvas.drawBitmap(starLightImg, drawStartX, 0, null); } else { if (remainNums > 0 && remainNums <= 1) {//画完后剩余半个不足一个的 //目标图片的宽和高 int ratingWidth = starLightImg.getWidth(); int ratingHeight = starLightImg.getHeight(); //需要画的宽度 int tw = (int) (ratingWidth * remainNums); //需要补充的背景 int bgw = ratingWidth - tw; if (tw > 0) {//绘制选中的部分 Bitmap b = Bitmap.createBitmap(starLightImg, 0, 0, tw, ratingHeight); canvas.drawBitmap(b, drawStartX, 0, null); } if (bgw > 0) {//绘制背景 Bitmap b = Bitmap.createBitmap(backgroundImg, tw, 0, bgw, ratingHeight); canvas.drawBitmap(b, drawStartX + tw, 0, null); } } else {//如果还有需要画的背景继续画 canvas.drawBitmap(backgroundImg, drawStartX, 0, null); } } } } @Override public boolean onTouchEvent(MotionEvent event) {//对手势做出监听 if (isIndicator())//如果是指示器,则不对点击做出响应 return false; //获取手势动作 int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_MOVE: //获取当前触点的位置 int positon = (int) getRelativePosition(event.getX()); //得到当前的星星数量 int start = positon + 1; //改变显示 if (start != rating) { setRating(start, true); } break; default: break; } return true; } private float getRelativePosition(float x) { float position = x / (bgWidth + space); position = Math.max(position, 0); return Math.min(position, starNums - 1); } void setRating(float rating, boolean fromUser) { if (rating > starNums) { this.rating = starNums; } this.rating = rating; invalidate(); dispatchRatingChange(fromUser); } /** * @param listener */ public void setOnRatingBarChangeListener(OnRatingBarChangeListener listener) { mOnRatingBarChangeListener = listener; } /** * @return */ public OnRatingBarChangeListener getOnRatingBarChangeListener() { return mOnRatingBarChangeListener; } void dispatchRatingChange(boolean fromUser) { if (mOnRatingBarChangeListener != null) { mOnRatingBarChangeListener.onRatingChanged(this, getRating(), fromUser); } } public void setStarNums(int startNums) { this.starNums = startNums; } public float getRating() { return rating; } public void setRating(float rating) { setRating(rating, false); } public boolean isIndicator() { return mIndicator; } public void setIndicator(boolean mIndicator) { this.mIndicator = mIndicator; } public void setType(int type) { this.type = type; } public void setSpace(int space) { this.space = space; } /** * dp-->px * * @param context * @param dp * @return */ private int dpToPx(Context context, int dp) { return (int) (context.getResources().getDisplayMetrics().density * dp + 0.5f); }}
自定义属性aatr.xml,可以根据需要添加
<resources> <declare-styleable name="HaisRatingBar"> <attr name="indicator" format="boolean" /> <attr name="rating" format="float" /> <attr name="numStars" format="integer" /> <attr name="starSpace" format="integer" /> <attr name="type" format="enum"> <enum name="normal" value="0" /> <enum name="small" value="1" /> </attr> <attr name="starBackground" format="reference" /> <attr name="starLight" format="reference" /> </declare-styleable></resources>
是不是感觉很简单呢?下面在activity中直接引用即可。
public class MainActivity extends Activity { private HaisRatingBar rating1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rating1 = (HaisRatingBar) findViewById(R.id.rating_main_01); rating1.setRating(3.6f); }}
简单的记录一下,为了以后学习方便,还有很多不足,希望聪明的你帮我指出。代码上传了还没显示出来,迟点把代码链接补上!
0 0
- 自定义ratingbar
- 自定义RatingBar
- 自定义RatingBar
- 自定义RatingBar
- 自定义RatingBar
- 自定义RatingBar
- 自定义RatingBar
- 自定义ratingbar
- 自定义RatingBar
- 自定义RatingBar
- RatingBar自定义样式
- android 自定义RatingBar图案
- RatingBar自定义效果
- Android自定义RatingBar && ProgressBar
- Android 自定义RatingBar样式
- android RatingBar自定义图片
- android RatingBar自定义图片
- android 自定义RatingBar图案
- Eclipse设置:背景与字体大小和xml文件中字体大小调整(转载)
- 浅谈《机房收费系统》重构中的Boolean和Datatable
- [BZOJ2631]tree
- android导入项目时提示:invalid project description的解决办法
- 基类和派生类
- 自定义RatingBar
- K60学习笔记五:串行通信的时序分析
- [CodeVs][1514][Treap][书架]
- Windows x64 Android开发环境搭建
- Java_SE05-Comparable,Map接口,队列,栈
- iOS学习笔记之UI-UISearchController-And-UITableView
- 给图像添加边界
- mysql 事务
- Handlebars.js 使用入门