博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android自定义View实现商品评价星星评分控件
阅读量:4077 次
发布时间:2019-05-25

本文共 6778 字,大约阅读时间需要 22 分钟。

先上图看实现效果:

这里写图片描述

这里写图片描述

首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性,只定义三个,有间距、分值和是否可以编辑:

自定义一个View继承LinearLayout,在构造方法中获取我们自定义的属性:

import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.View;import android.view.View.OnClickListener;import android.widget.ImageView;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;public class StarLinearLayout extends LinearLayout implements OnClickListener {
/** * 星星之间的间距 */ private int mMargin = 10; /** * 是否可点击 */ private boolean isEdit; /** * 初始的值 */ private float mScore = 0; private List
stars = new ArrayList<>(); public StarLinearLayout(Context context) { this(context, null); } public StarLinearLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public StarLinearLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if (attrs != null) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.star); mMargin = (int) a.getDimension(R.styleable.star_margin, 10); isEdit = a.getBoolean(R.styleable.star_isEdit, false); mScore = a.getFloat(R.styleable.star_score, 0); a.recycle(); } init(); setScore(mScore); }

在初始化的方法里面把星星动态添加进去(当然这里是用的图片),然后绑定点击的监听:

private void init() {        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);        params.weight = 1;        params.rightMargin = mMargin;        for (int i = 0; i < 5; i++) {            ImageView star = new ImageView(getContext());            star.setImageResource(R.mipmap.ic_star_select);            stars.add(star);            addView(star, params);            star.setOnClickListener(this);        }    }

下面就是设置分数和获取分数的方法(根据值来决定需要放置的星星图片):

public void setScore(float score) {        if (score < 0 || score > 5) score = 0;        mScore = score;        setStar(((int) (10 * score)) / 5);    }    public float getScore() {        return mScore;    }    private void setStar(int level) {        int i;        for (i = 0; i < level / 2; i++) {            stars.get(i).setImageResource(R.mipmap.ic_star_select);        }        if (level % 2 > 0) {            stars.get(i).setImageResource(R.mipmap.ic_star_select_half);            i++;        }        for (; i < stars.size(); i++) {            stars.get(i).setImageResource(R.mipmap.ic_star_unselect);        }    }

最后剩下就是添加监听:

@Override    public void onClick(View v) {        if (stars.contains(v)) {            if (!isEdit) return;            int index = stars.indexOf(v);            setScore(index + 1);            changeListener.Change(index + 1);        }    }    ChangeListener changeListener;    // 为每个接口设置监听器    public void setChangeListener(ChangeListener change) {        this.changeListener = change;    }    public interface ChangeListener {        void Change(int level);    }

activity中的代码:

public class MainActivity extends AppCompatActivity {
private StarLinearLayout mStar; private TextView tvScore; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mStar = (StarLinearLayout) findViewById(R.id.Star); tvScore = (TextView) findViewById(R.id.tv_score); mStar.setScore((float) 2.5); tvScore.setText("当前评分:" + mStar.getScore() + "分"); mStar.setChangeListener(new StarLinearLayout.ChangeListener() { @Override public void Change(int level) { tvScore.setText("当前评分:" + level + "分"); Toast.makeText(MainActivity.this, "您给了" + level + "分", Toast.LENGTH_LONG).show(); } }); }}

xml中的写法:

自定义类的全部代码:

import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.View;import android.view.View.OnClickListener;import android.widget.ImageView;import android.widget.LinearLayout;import java.util.ArrayList;import java.util.List;public class StarLinearLayout extends LinearLayout implements OnClickListener {
/** * 星星之间的间距 */ private int mMargin = 10; /** * 是否可点击 */ private boolean isEdit; /** * 初始的值 */ private float mScore = 0; private List
stars = new ArrayList<>(); public StarLinearLayout(Context context) { this(context, null); } public StarLinearLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public StarLinearLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); if (attrs != null) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.star); mMargin = (int) a.getDimension(R.styleable.star_margin, 10); isEdit = a.getBoolean(R.styleable.star_isEdit, false); mScore = a.getFloat(R.styleable.star_score, 0); a.recycle(); } init(); setScore(mScore); } private void init() { LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.weight = 1; params.rightMargin = mMargin; for (int i = 0; i < 5; i++) { ImageView star = new ImageView(getContext()); star.setImageResource(R.mipmap.ic_star_select); stars.add(star); addView(star, params); star.setOnClickListener(this); } } public void setScore(float score) { if (score < 0 || score > 5) score = 0; mScore = score; setStar(((int) (10 * score)) / 5); } public float getScore() { return mScore; } private void setStar(int level) { int i; for (i = 0; i < level / 2; i++) { stars.get(i).setImageResource(R.mipmap.ic_star_select); } if (level % 2 > 0) { stars.get(i).setImageResource(R.mipmap.ic_star_select_half); i++; } for (; i < stars.size(); i++) { stars.get(i).setImageResource(R.mipmap.ic_star_unselect); } } @Override public void onClick(View v) { if (stars.contains(v)) { if (!isEdit) return; int index = stars.indexOf(v); setScore(index + 1); changeListener.Change(index + 1); } } ChangeListener changeListener; // 为每个接口设置监听器 public void setChangeListener(ChangeListener change) { this.changeListener = change; } public interface ChangeListener {
void Change(int level); }}

源码地址:>

你可能感兴趣的文章
【泛型】一个简易的对象间转换的工具类(DO转VO)
查看>>
1.随机函数,计算机运行的基石
查看>>
MouseEvent的e.stageX是Number型,可见as3作者的考虑
查看>>
在mc中直接加aswing组件,该组件还需最后用validate()方法
查看>>
移植Vim配色方案到Eclipse
查看>>
从超链接调用ActionScript
查看>>
谈谈加密和混淆吧[转]
查看>>
TCP的几个状态对于我们分析所起的作用SYN, FIN, ACK, PSH,
查看>>
网络游戏客户端的日志输出
查看>>
关于按钮的mouseOver和rollOver
查看>>
《多线程服务器的适用场合》例释与答疑
查看>>
Netty框架
查看>>
Socket经验记录
查看>>
对RTMP视频流进行BitmapData.draw()出错的解决办法
查看>>
FMS 客户端带宽计算、带宽限制
查看>>
在线视频聊天(客服)系统开发那点事儿
查看>>
SecurityError Error 2148 SWF 不能访问本地资源
查看>>
Flex4的可视化显示对象
查看>>
Flex:自定义滚动条样式/隐藏上下箭头
查看>>
烈焰SWF解密
查看>>