Android中自定义RatingBar,自定义星星间距,自定义样式,自定义显示效果

来源:互联网 发布:mac装了双系统怎么切换 编辑:程序博客网 时间:2024/05/18 09:38

RatingBar是在等级,星级显示的时候,用的最多的,但是系统自带的效果,在星星间距大小上,以及将星星替换为其他造型上不能满足需求,所以需要自定义RatingBar;

自定义RatingBar非常简单:

一:简单的自定义(自定义样式)

1,确定展示出的选中和未选中两种状态的图片;

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android" >        <item android:id="@+android:id/background"        android:drawable="@drawable/star2"></item>                               <item android:id="@+android:id/secondaryProgress"                android:drawable="@drawable/star2"></item>                <item android:id="@+android:id/progress"        android:drawable="@drawable/star1"></item></layer-list>

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

对于星星之间的间距,可以通过切图,切图的透明底图的大小来试下控制,星星的间距。

2,自定义样式

<style name="yogaCourseRatingBar" parent="@android:style/Widget.RatingBar">        <item name="android:progressDrawable">@drawable/yota_ratingbar_progress_drawable</item>        <item name="android:minHeight">13dp</item>        <item name="android:maxHeight">13dp</item>    </style>

3,使用

<RatingBar         android:id="@+id/ratingStart"        android:layout_toRightOf="@id/difficultTV"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="0dp"        android:layout_alignBottom="@id/difficultTV"        android:numStars="5"        android:stepSize="1"        android:rating="2"        android:isIndicator="true"        android:layout_marginLeft="5dp"        style="@style/yogaCourseRatingBar"/>

效果:
这里写图片描述

isIndicator属性表示,展出的星星可不可以点击,true表示不可以点击,只是展示星级,false表示可以手动触摸点击,给出评价的等级,
这个属性,api中给的解释是:

Whether this rating bar is an indicator (and non-changeable by  the user). [boolean]

很简单,就是修改了系统给出的几个属性,修改了显示的星星图片,修改了展示星星的高度,

默认情况下,星星底部有一段空白高度,因为系统给的minHeight和maxHeight是57,远远超出了星星图片的高度,星星展示的时候默认靠上展示了,所以底部就空出了空袭,但是通过margin和padding都无法修改这个空白区域。

系统默认的RatingBar样式:

<style name="Widget.RatingBar">        <item name="indeterminateOnly">false</item>        <item name="progressDrawable">@drawable/ratingbar_full</item>        <item name="indeterminateDrawable">@drawable/ratingbar_full</item>        <item name="minHeight">57dip</item>        <item name="maxHeight">57dip</item>        <item name="thumb">@null</item>        <item name="mirrorForRtl">true</item>    </style>

这里写图片描述
看看系统给出的三种style的效果:

<RatingBar             android:id="@+id/rat1"            android:layout_below="@id/ratingStart"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:numStars="5"            android:rating="3"            style="@android:style/Widget.DeviceDefault.RatingBar.Small"/>        <RatingBar             android:id="@+id/rat2"            android:layout_below="@id/rat1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:numStars="5"            android:rating="2"            style="@android:style/Widget.DeviceDefault.RatingBar"/>        <RatingBar             android:layout_below="@id/rat2"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:numStars="5"            android:rating="4"            style="@android:style/Widget.DeviceDefault.RatingBar.Indicator"/>

效果:(发现选中后的颜色,似乎不好控制啊,需要通过primaryColor来控制,这是APP的主色调,耦合度这么高,不好呀)
这里写图片描述

二:继承一个View,自定义一个RatingBarView控件(较深程度的自定义–自定义控件)

实现也是很简单的:
通过这个自定义,完全可以控制心心的大小、形状、图案,间距,点击回调事件处理,都可以处理了。

因为他其实是通过在一个viewgroup中addimageview来实现的。

这里写图片描述

/** *  * TODO(自定义ratingbar) * @author yujie.zhang * 2017-4-10下午8:34:57 */public class RatingBarView extends LinearLayout {    public interface OnRatingListener {        void onRating(Object bindObject, int RatingScore);    }    private boolean mClickable = true;    private OnRatingListener onRatingListener;    private Object bindObject;    private float starImageSize;    private int starCount;    private Drawable starEmptyDrawable;    private Drawable starFillDrawable;    private int mStarCount;    public void setClickable(boolean clickable) {        this.mClickable = clickable;    }    public RatingBarView(Context context, AttributeSet attrs) {        super(context, attrs);        setOrientation(LinearLayout.HORIZONTAL);        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RatingBarView);        starImageSize = ta.getDimension(R.styleable.RatingBarView_starImageSize, 20);        starCount = ta.getInteger(R.styleable.RatingBarView_starCount, 5);        starEmptyDrawable = ta.getDrawable(R.styleable.RatingBarView_starEmpty);        starFillDrawable = ta.getDrawable(R.styleable.RatingBarView_starFill);        ta.recycle();        for (int i = 0; i < starCount; ++i) {            ImageView imageView = getStarImageView(context, attrs);            imageView.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    if (mClickable) {                        mStarCount = indexOfChild(v) + 1;                        setStar(mStarCount, true);                        if (onRatingListener != null) {                            onRatingListener.onRating(bindObject, mStarCount);                        }                    }                }            });            addView(imageView);        }    }    private ImageView getStarImageView(Context context, AttributeSet attrs) {        ImageView imageView = new ImageView(context);        ViewGroup.LayoutParams para = new ViewGroup.LayoutParams(Math.round(starImageSize), Math.round(starImageSize));        imageView.setLayoutParams(para);        // TODO:you can change gap between two stars use the padding//        imageView.setPadding(0, 0, 40, 0);        imageView.setPadding(0, 0, 0, 0);        imageView.setImageDrawable(starEmptyDrawable);        imageView.setMaxWidth(10);        imageView.setMaxHeight(10);        return imageView;    }    public void setStar(int starCount, boolean animation) {        starCount = starCount > this.starCount ? this.starCount : starCount;        starCount = starCount < 0 ? 0 : starCount;        for (int i = 0; i < starCount; ++i) {            ((ImageView) getChildAt(i)).setImageDrawable(starFillDrawable);            if (animation) {                ScaleAnimation sa = new ScaleAnimation(0, 0, 1, 1);                getChildAt(i).startAnimation(sa);            }        }        for (int i = this.starCount - 1; i >= starCount; --i) {            ((ImageView) getChildAt(i)).setImageDrawable(starEmptyDrawable);        }    }    public int getStarCount() {        return mStarCount;    }    public void setStarFillDrawable(Drawable starFillDrawable) {        this.starFillDrawable = starFillDrawable;    }    public void setStarEmptyDrawable(Drawable starEmptyDrawable) {        this.starEmptyDrawable = starEmptyDrawable;    }    public void setStarCount(int startCount) {        this.starCount = startCount;    }    public void setStarImageSize(float starImageSize) {        this.starImageSize = starImageSize;    }    public void setBindObject(Object bindObject) {        this.bindObject = bindObject;    }/***这个回调,可以获取到用户评价给出的星星等级*/    public void setOnRatingListener(OnRatingListener onRatingListener) {        this.onRatingListener = onRatingListener;    }}

值得注意的是,需要在attr文件中自定义几个styleable属性样式:

<declare-styleable name="RatingBarView">        <attr name="starImageSize" format="dimension"/>        <attr name="starCount" format="integer"/>        <attr name="starEmpty" format="reference"/>        <attr name="starFill" format="reference"/>    </declare-styleable>

剩下的几个styleable,是系统提供的,查找的时候,发现直接通过我们定义的这个styleable映射到了系统的styleable资源去了。

使用:
xml中:

<com.family.heyqun.moudle_home_page.tool.RatingBarView            xmlns:app="http://schemas.android.com/apk/res-auto"            android:id="@+id/custom_ratingbar"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_vertical"            app:starCount="5"            app:starEmpty="@drawable/staroff"            app:starFill="@drawable/staron"            app:starImageSize="50dp" />

在MainActivity中:

int level=0;RatingBarView custom_ratingbar=(RatingBarView)findViewById(R.id.ratingbar);custom_ratingbar                .setOnRatingListener(new RatingBarView.OnRatingListener() {                    @Override                    public void onRating(Object bindObject, int ratingScore) {                        Toast.makeText(FeedBackEvaluateActivity.this,                               String.valueOf(ratingScore), Toast.LENGTH_SHORT)                                .show();                        level = ratingScore;                    }                });

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

阅读全文
1 0
原创粉丝点击