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

先上图看实现效果:
Android自定义View实现商品评价星星评分控件_第1张图片

Android自定义View实现商品评价星星评分控件_第2张图片

首先在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

你可能感兴趣的:(Android开发)