自定义的星级评分 starBar

样式图:


StarBar类:

[java]  view plain  copy
  1. package com.lym.starbar2;  
  2.   
  3. import android.content.Context;  
  4. import android.content.res.TypedArray;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.BitmapShader;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Paint;  
  9. import android.graphics.drawable.Drawable;  
  10. import android.util.AttributeSet;  
  11. import android.view.MotionEvent;  
  12. import android.view.View;  
  13.   
  14. /** 
  15.  * Created by DMing on 2016/7/18. 
  16.  * 
  17.  */  
  18. public class StarBar extends View{  
  19.     private int starDistance = 0//星星间距  
  20.     private int starCount = 5;  //星星个数  
  21.     private int starSize;     //星星高度大小,星星一般正方形,宽度等于高度  
  22.     private float starMark = 0.0F;   //评分星星  
  23.     private Bitmap starFillBitmap; //亮星星  
  24.     private Drawable starEmptyDrawable; //暗星星  
  25.     private OnStarChangeListener onStarChangeListener;//监听星星变化接口  
  26.     private Paint paint;         //绘制星星画笔  
  27.     private boolean integerMark = false;  
  28.     public StarBar(Context context, AttributeSet attrs) {  
  29.         super(context, attrs);  
  30.         init(context, attrs);  
  31.     }  
  32.   
  33.     public StarBar(Context context, AttributeSet attrs, int defStyleAttr) {  
  34.         super(context, attrs, defStyleAttr);  
  35.         init(context, attrs);  
  36.     }  
  37.   
  38.     /** 
  39.      * 初始化UI组件 
  40.      * 
  41.      * @param context 
  42.      * @param attrs 
  43.      */  
  44.     private void init(Context context, AttributeSet attrs){  
  45.         setClickable(true);  
  46.         TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RatingBar);  
  47.         this.starDistance = (int) mTypedArray.getDimension(R.styleable.RatingBar_starDistance, 0);  
  48.         this.starSize = (int) mTypedArray.getDimension(R.styleable.RatingBar_starSize, 20);  
  49.         this.starCount = mTypedArray.getInteger(R.styleable.RatingBar_starCount, 5);  
  50.         this.starEmptyDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starEmpty);  
  51.         this.starFillBitmap =  drawableToBitmap(mTypedArray.getDrawable(R.styleable.RatingBar_starFill));  
  52.         mTypedArray.recycle();  
  53.   
  54.         paint = new Paint();  
  55.         paint.setAntiAlias(true);  
  56.         paint.setShader(new BitmapShader(starFillBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));  
  57.     }  
  58.   
  59.     /** 
  60.      * 设置是否需要整数评分 
  61.      * @param integerMark 
  62.      */  
  63.     public void setIntegerMark(boolean integerMark){  
  64.         this.integerMark = integerMark;  
  65.     }  
  66.   
  67.     /** 
  68.      * 设置显示的星星的分数 
  69.      * 
  70.      * @param mark 
  71.      */  
  72.     public void setStarMark(float mark){  
  73.         if (integerMark) {  
  74.             starMark = (int)Math.ceil(mark);  
  75.         }else {  
  76.             starMark = Math.round(mark * 10) * 1.0f / 10;  
  77.         }  
  78.         if (this.onStarChangeListener != null) {  
  79.             this.onStarChangeListener.onStarChange(starMark);  //调用监听接口  
  80.         }  
  81.         invalidate();  
  82.     }  
  83.   
  84.     /** 
  85.      * 获取显示星星的数目 
  86.      * 
  87.      * @return starMark 
  88.      */  
  89.     public float getStarMark(){  
  90.         return starMark;  
  91.     }  
  92.   
  93.   
  94.     /** 
  95.      * 定义星星点击的监听接口 
  96.      */  
  97.     public interface OnStarChangeListener {  
  98.         void onStarChange(float mark);  
  99.     }  
  100.   
  101.     /** 
  102.      * 设置监听 
  103.      * @param onStarChangeListener 
  104.      */  
  105.     public void setOnStarChangeListener(OnStarChangeListener onStarChangeListener){  
  106.         this.onStarChangeListener = onStarChangeListener;  
  107.     }  
  108.   
  109.     @Override  
  110.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  111.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  112.         setMeasuredDimension(starSize * starCount + starDistance * (starCount - 1), starSize);  
  113.     }  
  114.   
  115.     @Override  
  116.     protected void onDraw(Canvas canvas) {  
  117.         super.onDraw(canvas);  
  118.         if (starFillBitmap == null || starEmptyDrawable == null) {  
  119.             return;  
  120.         }  
  121.         for (int i = 0;i < starCount;i++) {  
  122.             starEmptyDrawable.setBounds((starDistance + starSize) * i, 0, (starDistance + starSize) * i + starSize, starSize);  
  123.             starEmptyDrawable.draw(canvas);  
  124.         }  
  125.         if (starMark > 1) {  
  126.             canvas.drawRect(00, starSize, starSize, paint);  
  127.             if(starMark-(int)(starMark) == 0) {  
  128.                 for (int i = 1; i < starMark; i++) {  
  129.                     canvas.translate(starDistance + starSize, 0);  
  130.                     canvas.drawRect(00, starSize, starSize, paint);  
  131.                 }  
  132.             }else {  
  133.                 for (int i = 1; i < starMark - 1; i++) {  
  134.                     canvas.translate(starDistance + starSize, 0);  
  135.                     canvas.drawRect(00, starSize, starSize, paint);  
  136.                 }  
  137.                 canvas.translate(starDistance + starSize, 0);  
  138.                 canvas.drawRect(00, starSize * (Math.round((starMark - (int) (starMark))*10)*1.0f/10), starSize, paint);  
  139.             }  
  140.         }else {  
  141.             canvas.drawRect(00, starSize * starMark, starSize, paint);  
  142.         }  
  143.     }  
  144.   
  145.   
  146.     @Override  
  147.     public boolean onTouchEvent(MotionEvent event) {  
  148.         int x = (int) event.getX();  
  149.         if (x < 0) x = 0;  
  150.         if (x > getMeasuredWidth()) x = getMeasuredWidth();  
  151.         switch(event.getAction()){  
  152.             case MotionEvent.ACTION_DOWN: {  
  153.                 setStarMark(x*1.0f / (getMeasuredWidth()*1.0f/starCount));  
  154.                 break;  
  155.             }  
  156.             case MotionEvent.ACTION_MOVE: {  
  157.                 setStarMark(x*1.0f / (getMeasuredWidth()*1.0f/starCount));  
  158.                 break;  
  159.             }  
  160.             case MotionEvent.ACTION_UP: {  
  161.                 break;  
  162.             }  
  163.         }  
  164.         invalidate();  
  165.         return super.onTouchEvent(event);  
  166.     }  
  167.   
  168.     /** 
  169.      * drawable转bitmap 
  170.      * 
  171.      * @param drawable 
  172.      * @return 
  173.      */  
  174.     private Bitmap drawableToBitmap(Drawable drawable)  
  175.     {  
  176.         if (drawable == null)return null;  
  177.         Bitmap bitmap = Bitmap.createBitmap(starSize, starSize, Bitmap.Config.ARGB_8888);  
  178.         Canvas canvas = new Canvas(bitmap);  
  179.         drawable.setBounds(00, starSize, starSize);  
  180.         drawable.draw(canvas);  
  181.         return bitmap;  
  182.     }  
  183. }  
attrs.xml:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.     <declare-styleable name="RatingBar">  
  5.   
  6.         <!-- 星星间距 -->  
  7.         <attr name="starDistance" format="dimension" />  
  8.         <!-- 星星大小 -->  
  9.         <attr name="starSize" format="dimension" />  
  10.         <!-- 星星个数 -->  
  11.         <attr name="starCount" format="integer" />  
  12.         <!-- 星星空图 -->  
  13.         <attr name="starEmpty" format="reference" />  
  14.         <!-- 星星满图 -->  
  15.         <attr name="starFill" format="reference" />  
  16.     </declare-styleable>  
  17.   
  18. </resources>  

test.xml文件(页面文件)

[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:RatingBar="http://schemas.android.com/apk/res/com.lym.starbar2"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical"  
  7.     android:padding="10dp" >  
  8.   
  9.     <com.lym.starbar2.StarBar  
  10.         android:id="@+id/starBar"  
  11.         android:layout_width="wrap_content"  
  12.         android:layout_height="wrap_content"  
  13.         RatingBar:starCount="5"  
  14.         RatingBar:starDistance="10dp"  
  15.         RatingBar:starEmpty="@drawable/star_gray"  
  16.         RatingBar:starFill="@drawable/star_yellow"  
  17.         RatingBar:starSize="30dp" />  
  18.   
  19. </LinearLayout>  

如果引用控件报错,可以在所在布局里面加上下面的代码

[html]  view plain  copy
  1. xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     xmlns:RatingBar="http://schemas.android.com/apk/res-auto"  


demo下载demo下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值