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;
}
});
本文介绍了如何在Android中自定义RatingBar,包括调整星星间距、设置自定义样式以及创建可定制的显示效果。通过切图控制间距,自定义View实现深度定制,同时讲解了自定义控件的实现过程和使用方法。
809

被折叠的 条评论
为什么被折叠?



