自定義的星級評分 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下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章