由于公司需求要做一个游戏推荐的功能,其中涉及到一个评分功能。
初步想法是使用Android系统自带的RatingBar,但是由于修改样式比较费劲。干脆自己来一发。
言归正传:直接上效果图
功能:
1.可以配置未选中的样式以及选中的样式
2.可以配置总个数以及默认选中的个数
3.点击第几个项目,之前的以及此项目显示选中状态,后面的为未选中状态。
4.可以获取分数。
思路:
1.自定义属性,使用TypedArray在代码中获取
<declare-styleable name="MyRatingView"> <attr name="totalStarNum" format="integer"></attr> <attr name="markNum" format="integer"></attr> <attr name="lightDrawable" format="reference"></attr> <attr name="blackDrawable" format="reference"></attr> </declare-styleable>
TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.MyRatingView); starNum=typedArray.getInt(R.styleable.MyRatingView_totalStarNum,5); markNum=typedArray.getInt(R.styleable.MyRatingView_markNum,3); lightDrawable=typedArray.getDrawable(R.styleable.MyRatingView_lightDrawable); blackDrawable=typedArray.getDrawable(R.styleable.MyRatingView_blackDrawable); typedArray.recycle();
2.每一个项目都是一个ImageView,所以建立一个大小为totalStarNum的ImageView数组用于存储所有的ImageView。并根据markNum初始化每个ImageView显示的图片。
3.给每个图片都加一个监听器,点击后更新markNum及所有ImageView的显示样式。怎样知道点了哪个呢?方法很多,我这里使用的是View的setTag()
直接上源码
MyRatingView.java
package com.david.myratingbar; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; public class MyRatingView extends LinearLayout implements View.OnClickListener { private int starNum = 5; private int markNum = 3; private Drawable lightDrawable,blackDrawable; private ImageView[] imageViews; public MyRatingView(Context context) { this(context,null); } public MyRatingView(Context context, AttributeSet attrs) { this(context,attrs,0); } public MyRatingView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.MyRatingView); starNum=typedArray.getInt(R.styleable.MyRatingView_totalStarNum,5); markNum=typedArray.getInt(R.styleable.MyRatingView_markNum,3); lightDrawable=typedArray.getDrawable(R.styleable.MyRatingView_lightDrawable); blackDrawable=typedArray.getDrawable(R.styleable.MyRatingView_blackDrawable); typedArray.recycle(); if(starNum<markNum){ throw new RuntimeException("staNum must > markNum"); } init(context); } private void init(Context context) { this.setOrientation(HORIZONTAL); imageViews = new ImageView[starNum]; for (int i = 0; i < markNum; i++) { ImageView imageView = new ImageView(context); imageView.setImageDrawable(lightDrawable); imageView.setTag(i); imageView.setOnClickListener(this); imageViews[i] = imageView; this.addView(imageView); } for (int i = markNum; i < starNum; i++) { ImageView imageView = new ImageView(context); imageView.setTag(i); imageView.setImageDrawable(blackDrawable); imageView.setOnClickListener(this); imageViews[i] = imageView; this.addView(imageView); } } @Override public void onClick(View v) { int clickIndex = (int) v.getTag(); markNum = clickIndex + 1; for (int i = 0; i <= clickIndex; i++) { imageViews[i].setImageDrawable(lightDrawable); } for (int i = clickIndex + 1; i < imageViews.length; i++) { imageViews[i].setImageDrawable(blackDrawable); } } public int getScore() { return markNum; } }
<com.david.myratingbar.MyRatingView android:layout_marginTop="200dp" android:layout_width="wrap_content" android:layout_height="wrap_content" david:lightDrawable="@drawable/ic_star_checked" david:blackDrawable="@drawable/ic_star_normal" david:markNum="5" david:totalStarNum="7" />