热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android自定义View实现商品评价星星评分控件

先上图看实现效果:首先在resvalues下建立一个attrs.xml,在里面定义我们的属性,只定义三个,有间距、分值和是否

先上图看实现效果:
这里写图片描述

这里写图片描述

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

<declare-styleable name&#61;"star"><attr name&#61;"margin" format&#61;"dimension|reference"/><attr name&#61;"isEdit" format&#61;"boolean"/><attr name&#61;"score" format&#61;"float"/>declare-styleable>

自定义一个View继承LinearLayout&#xff0c;在构造方法中获取我们自定义的属性&#xff1a;

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 &#61; 10;/*** 是否可点击*/private boolean isEdit;/*** 初始的值*/private float mScore &#61; 0;private List stars &#61; 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 !&#61; null) {TypedArray a &#61; context.obtainStyledAttributes(attrs, R.styleable.star);mMargin &#61; (int) a.getDimension(R.styleable.star_margin, 10);isEdit &#61; a.getBoolean(R.styleable.star_isEdit, false);mScore &#61; a.getFloat(R.styleable.star_score, 0);a.recycle();}init();setScore(mScore);}

在初始化的方法里面把星星动态添加进去&#xff08;当然这里是用的图片&#xff09;&#xff0c;然后绑定点击的监听&#xff1a;

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

下面就是设置分数和获取分数的方法&#xff08;根据值来决定需要放置的星星图片&#xff09;&#xff1a;

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

最后剩下就是添加监听&#xff1a;

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

activity中的代码&#xff1a;

public class MainActivity extends AppCompatActivity {private StarLinearLayout mStar;private TextView tvScore;&#64;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mStar &#61; (StarLinearLayout) findViewById(R.id.Star);tvScore &#61; (TextView) findViewById(R.id.tv_score);mStar.setScore((float) 2.5);tvScore.setText("当前评分&#xff1a;" &#43; mStar.getScore() &#43; "分");mStar.setChangeListener(new StarLinearLayout.ChangeListener() {&#64;Overridepublic void Change(int level) {tvScore.setText("当前评分&#xff1a;" &#43; level &#43; "分");Toast.makeText(MainActivity.this, "您给了" &#43; level &#43; "分", Toast.LENGTH_LONG).show();}});}
}

xml中的写法&#xff1a;


<LinearLayout xmlns:android&#61;"http://schemas.android.com/apk/res/android"xmlns:app&#61;"http://schemas.android.com/apk/res-auto"xmlns:tools&#61;"http://schemas.android.com/tools"android:layout_width&#61;"match_parent"android:layout_height&#61;"match_parent"android:orientation&#61;"vertical"android:gravity&#61;"center"tools:context&#61;"com.xp.stardemo.MainActivity"><TextView
android:id&#61;"&#64;&#43;id/tv_score"android:layout_width&#61;"wrap_content"android:layout_height&#61;"wrap_content"/>
<com.xp.stardemo.StarLinearLayout
android:layout_marginTop&#61;"10dp"android:layout_width&#61;"wrap_content"android:layout_height&#61;"wrap_content"android:id&#61;"&#64;&#43;id/Star"app:isEdit&#61;"true"/>
LinearLayout>

自定义类的全部代码&#xff1a;

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 &#61; 10;/*** 是否可点击*/private boolean isEdit;/*** 初始的值*/private float mScore &#61; 0;private List stars &#61; 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 !&#61; null) {TypedArray a &#61; context.obtainStyledAttributes(attrs, R.styleable.star);mMargin &#61; (int) a.getDimension(R.styleable.star_margin, 10);isEdit &#61; a.getBoolean(R.styleable.star_isEdit, false);mScore &#61; a.getFloat(R.styleable.star_score, 0);a.recycle();}init();setScore(mScore);}private void init() {LayoutParams params &#61; new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);params.weight &#61; 1;params.rightMargin &#61; mMargin;for (int i &#61; 0; i <5; i&#43;&#43;) {ImageView star &#61; 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 &#61; 0;mScore &#61; score;setStar(((int) (10 * score)) / 5);}public float getScore() {return mScore;}private void setStar(int level) {int i;for (i &#61; 0; i 2; i&#43;&#43;) {stars.get(i).setImageResource(R.mipmap.ic_star_select);}if (level % 2 > 0) {stars.get(i).setImageResource(R.mipmap.ic_star_select_half);i&#43;&#43;;}for (; i &#64;Overridepublic void onClick(View v) {if (stars.contains(v)) {if (!isEdit) return;int index &#61; stars.indexOf(v);setScore(index &#43; 1);changeListener.Change(index &#43; 1);}}ChangeListener changeListener;// 为每个接口设置监听器public void setChangeListener(ChangeListener change) {this.changeListener &#61; change;}public interface ChangeListener {void Change(int level);}
}

源码地址&#xff1a;> http://download.csdn.net/detail/silenceoo/9883042


推荐阅读
author-avatar
lk神密勇士
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有