首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性,只定义三个,有间距、分值和是否可以编辑:
<declare-styleable name="star">
<attr name="margin" format="dimension|reference"/>
<attr name="isEdit" format="boolean"/>
<attr name="score" format="float"/>
declare-styleable>
自定义一个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中的写法:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context="com.xp.stardemo.MainActivity">
<TextView
android:id="@+id/tv_score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<com.xp.stardemo.StarLinearLayout
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Star"
app:isEdit="true"
/>
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);
}
}
源码地址:> http://download.csdn.net/detail/silenceoo/9883042