android自定义RatingBar

本文介绍了如何在Android中自定义RatingBar控件,解决原生控件样式、颜色、大小等问题。通过创建attrs.xml文件,新建继承LinearLayout的RatingBar类,并实现初始化星星ImageView、设置评分、评分监听接口等功能,实现高度定制的评分条。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


个人感觉,android自带的那个评分控件实在是坑爹的,想要换个样式,颜色,大小,间距什么的,各种状况漫天飞,用着各种不爽。看了一位大神的文章,再加上自己琢磨一下,今天用linearlayout,自己搞个ratingbar,效果还是相当不错的。


自定义ratingbar控件

1.首先在res/values下面新建一个attrs.xml文件

内容如下

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RatingBar">
        <!--星星大小-->
        <attr format="dimension" name="starImageSize"/>
        <!--星星个数-->
        <attr format="integer" name="starCount"/>
        <!--星星空图-->
        <attr format="reference" name="starEmpty"/>
        <!--星星满图-->
        <attr format="reference" name="starFill"/>
        <!--星星半图-->
        <attr format="reference" name="starHalf"/>
        <!--是否可以点击评分-->
        <attr format="boolean" name="clickable"/>
    </declare-styleable>

</resources>

2.新建一个类RatingBar继承LinearLayout

RatingBar extends LinearLayout


定义变量

private boolean mClickable;
private int starCount;
private RatingBar.OnRatingChangeListener onRatingChangeListener;
private float starImageSize;
private Drawable starEmptyDrawable;
private Drawable starFillDrawable;
private Drawable starHalfDrawable;


并实现构造方法

public RatingBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.setOrientation(HORIZONTAL);
    TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RatingBar);
    this.starImageSize = mTypedArray.getDimension(R.styleable.RatingBar_starImageSize, 20.0F);
    this.starCount = mTypedArray.getInteger(R.styleable.RatingBar_starCount, 5);
    this.starEmptyDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starEmpty);
    this.starFillDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starFill);
    this.starHalfDrawable=mTypedArray.getDrawable(R.styleable.RatingBar_starHalf);
    this.mClickable = mTypedArray.getBoolean(R.styleable.RatingBar_clickable, false);

    mTypedArray.recycle();

    for (int i = 0; i < this.starCount; ++i) {
        ImageView imageView = this.getStarImageView(context, attrs);
        imageView.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (RatingBar.this.mClickable) {  //判断星星可以点击
                    RatingBar.this.setStar(RatingBar.this.indexOfChild(v) + 1);  //设置当前评分
                    if (RatingBar.this.onRatingChangeListener != null) {
                        RatingBar.this.onRatingChangeListener.onRatingChange(RatingBar.this.indexOfChild(v) + 1);  //调用监听接口
                    }
                }
            }
        });
        this.addView(imageView);
    }

}

3.写一个方法初始化星星imageview

//初始化单个星星控件
private ImageView getStarImageView(Context context, AttributeSet attrs) {
    ImageView imageView = new ImageView(context);
    LayoutParams para = new LayoutParams(Math.round(this.starImageSize), Math.round(this.starImageSize));
    imageView.setLayoutParams(para);
    imageView.setPadding(0, 0, 5, 0);
    imageView.setImageDrawable(this.starEmptyDrawable);
    imageView.setMaxWidth(10);
    imageView.setMaxHeight(10);
    return imageView;
}

4.写一个方法设置当前评分

//设置当前评分
public void setStar(float mark) {

    //判断评分,不能大于星星总数,不能小于0
    mark = mark > this.starCount ? this.starCount : mark;
    mark = starCount < 0 ? 0 : mark;

    float xiaoshu=mark-(int)(mark); //计算分数的小数部分
    int zhengshu=(int)mark; //计算分数的整数部分

    //显示整数部分的星星,全部是实心星星
    for (int i = 0; i < zhengshu; ++i) {
        ((ImageView) this.getChildAt(i)).setImageDrawable(this.starFillDrawable);
    }

    //显示小数部分的星星
    if(xiaoshu>0)//如果小数部分大于0,则显示半分星星,当然这里可以做更加精确一点的判断
    {
        if(zhengshu<this.starCount)
        ((ImageView) this.getChildAt(zhengshu)).setImageDrawable(this.starHalfDrawable);
    }else   //如果小数部分小于或等于0,显示全空星星
    {
        if(zhengshu<this.starCount)
        ((ImageView) this.getChildAt(zhengshu)).setImageDrawable(this.starEmptyDrawable);
    }

   //剩余部分用全空星星显示
    for(int j=++zhengshu;j<this.starCount;j++)
    {
        ((ImageView) this.getChildAt(j)).setImageDrawable(this.starEmptyDrawable);
    }

}

5.定义评分监听接口,用于点击评分时回调

//定义星星点击的监听接口
public interface OnRatingChangeListener {
    void onRatingChange(int var1);
}

以上几个方法都在构造方法里调用了,注释写得很详细,相信很容易看懂


6.使用

在xml布局文件使用

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:ratingbar="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="#000">

    <ratingbar.carr.myratingbar.RatingBar
        android:id="@+id/ratingbar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:layout_centerInParent="true"
        ratingbar:starCount="5"
        ratingbar:clickable="false"
        ratingbar:starEmpty="@mipmap/star_empty"
        ratingbar:starFill="@mipmap/star_full"
        ratingbar:starHalf="@mipmap/star_half"
        ratingbar:starImageSize="30dp"/>

</RelativeLayout>
注意加上声明
xmlns:ratingbar="http://schemas.android.com/apk/res-auto"

以及自定义控件的使用要使用全名


在activity代码中

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ratingBar=(RatingBar)findViewById(R.id.ratingbar);
    ratingBar.setmClickable(true);
    ratingBar.setOnRatingChangeListener(new RatingBar.OnRatingChangeListener() {
        @Override
        public void onRatingChange(int var1) {
            Toast.makeText(MainActivity.this,"你的评分:"+var1,Toast.LENGTH_SHORT).show();
        }
    });
}
就是这么简单。

有了这个,就可以随意改变控件的样式了,换图标背景啊,间距啊,大小啊,个数啊,全都不是问题,杠杠的!


源码在这:http://download.youkuaiyun.com/detail/qq_17681243/9207631

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值