1.自定义attrs
<resources xmlns:tools="http://schemas.android.com/tools">
<declare-styleable name="RatingBar" tools:ignore="ResourceName">
<attr name="starImageSize" format="dimension"/>
<attr name="starImageWidth" format="dimension"/>
<attr name="starImageHeight" format="dimension"/>
<attr name="starImagePadding" format="dimension"/>
<attr name="starCount" format="integer"/>
<attr name="starNum" format="integer"/>
<attr name="starEmpty" format="reference"/>
<attr name="starFill" format="reference"/>
<attr name="starHalf" format="reference"/>
<attr name="clickable" format="boolean"/>
<attr name="halfstart" format="boolean"/>
</declare-styleable>
</resources>
2.自定义控件代码
/**
* Created by hedge_hog on 2015/06/11.
* update by hedge_hog on 2016/08/06
*/
public class RatingBar extends LinearLayout {
private boolean mClickable;
private boolean halfstart;
private int starCount;
private int starNum;
private OnRatingChangeListener onRatingChangeListener;
private float starImageSize;
private float starImageWidth;
private float starImageHeight;
private float starImagePadding;
private Drawable starEmptyDrawable;
private Drawable starFillDrawable;
private Drawable starHalfDrawable;
private int y = 1;
private boolean isEmpty=true;
public void setStarHalfDrawable(Drawable starHalfDrawable) {
this.starHalfDrawable = starHalfDrawable;
}
public void setOnRatingChangeListener(OnRatingChangeListener onRatingChangeListener) {
this.onRatingChangeListener = onRatingChangeListener;
}
public void setmClickable(boolean clickable) {
this.mClickable = clickable;
}
public void halfStar(boolean halfstart) {
this.halfstart = halfstart;
}
public void setStarFillDrawable(Drawable starFillDrawable) {
this.starFillDrawable = starFillDrawable;
}
public void setStarEmptyDrawable(Drawable starEmptyDrawable) {
this.starEmptyDrawable = starEmptyDrawable;
}
public void setStarImageSize(float starImageSize) {
this.starImageSize = starImageSize;
}
public void setStarImageWidth(float starImageWidth) {
this.starImageWidth = starImageWidth;
}
public void setStarImageHeight(float starImageHeight) {
this.starImageHeight = starImageHeight;
}
public void setStarCount(int starCount) {
this.starCount = starCount;
}
public void setImagePadding(float starImagePadding) {
this.starImagePadding = starImagePadding;
}
public RatingBar(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(LinearLayout.HORIZONTAL);
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RatingBar);
starHalfDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starHalf);
starEmptyDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starEmpty);
starFillDrawable = mTypedArray.getDrawable(R.styleable.RatingBar_starFill);
starImageSize = mTypedArray.getDimension(R.styleable.RatingBar_starImageSize, 120);
starImageWidth = mTypedArray.getDimension(R.styleable.RatingBar_starImageWidth, 60);
starImageHeight = mTypedArray.getDimension(R.styleable.RatingBar_starImageHeight, 120);
starImagePadding = mTypedArray.getDimension(R.styleable.RatingBar_starImagePadding, 15);
starCount = mTypedArray.getInteger(R.styleable.RatingBar_starCount, 5);
starNum = mTypedArray.getInteger(R.styleable.RatingBar_starNum, 0);
mClickable = mTypedArray.getBoolean(R.styleable.RatingBar_clickable, true);
halfstart = mTypedArray.getBoolean(R.styleable.RatingBar_halfstart, false);
for (int i = 0; i < starNum; ++i) {
ImageView imageView = getStarImageView(context,false);
addView(imageView);
}
for (int i = 0; i < starCount; ++i) {
ImageView imageView = getStarImageView(context,isEmpty);
imageView.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
if (mClickable) {
if (halfstart) {
//TODO:This is not the best way to solve half a star,
//TODO:but That's what I can do,Please let me know if you have a better solution
if (y % 2 == 0) {
setStar(indexOfChild(v) + 1f);
} else {
setStar(indexOfChild(v) + 0.5f);
}
if (onRatingChangeListener != null) {
if (y % 2 == 0) {
onRatingChangeListener.onRatingChange(indexOfChild(v) + 1f);
y++;
} else {
onRatingChangeListener.onRatingChange(indexOfChild(v) + 0.5f);
y++;
}
}
} else {
setStar(indexOfChild(v) + 1f);
if (onRatingChangeListener != null) {
onRatingChangeListener.onRatingChange(indexOfChild(v) + 1f);
}
}
}
}
}
);
addView(imageView);
}
}
private ImageView getStarImageView(Context context,boolean isEmpty) {
ImageView imageView = new ImageView(context);
ViewGroup.LayoutParams para = new ViewGroup.LayoutParams(
Math.round(starImageWidth),
Math.round(starImageHeight)
);
imageView.setLayoutParams(para);
imageView.setPadding(0, 0, Math.round(starImagePadding), 0);
if(isEmpty){
imageView.setImageDrawable(starEmptyDrawable);
}else{
imageView.setImageDrawable(starFillDrawable);
}
return imageView;
}
public void setStar(float starCount) {
int fint = (int) starCount;
BigDecimal b1 = new BigDecimal(Float.toString(starCount));
BigDecimal b2 = new BigDecimal(Integer.toString(fint));
float fPoint = b1.subtract(b2).floatValue();
starCount = fint > this.starCount ? this.starCount : fint;
starCount = starCount < 0 ? 0 : starCount;
//drawfullstar
for (int i = 0; i < starCount; ++i) {
((ImageView) getChildAt(i)).setImageDrawable(starFillDrawable);
}
//drawhalfstar
if (fPoint > 0) {
((ImageView) getChildAt(fint)).setImageDrawable(starHalfDrawable);
//drawemptystar
for (int i = this.starCount - 1; i >= starCount + 1; --i) {
((ImageView) getChildAt(i)).setImageDrawable(starEmptyDrawable);
}
} else {
//drawemptystar
for (int i = this.starCount - 1; i >= starCount; --i) {
((ImageView) getChildAt(i)).setImageDrawable(starEmptyDrawable);
}
}
}
/**
* change start listener
*/
public interface OnRatingChangeListener {
void onRatingChange(float RatingCount);
}
}
3.调用
public class MainActivity extends AppCompatActivity {
RatingBar mRatingBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRatingBar=findViewById(R.id.ratingbar);
mRatingBar.setStarEmptyDrawable(getResources().getDrawable(R.mipmap.star_empty));
mRatingBar.setStarHalfDrawable(getResources().getDrawable(R.mipmap.star_half));
mRatingBar.setStarFillDrawable(getResources().getDrawable(R.mipmap.star_full));
mRatingBar.setStarCount(5);
mRatingBar.setStar(2.5f);
mRatingBar.halfStar(true);
mRatingBar.setmClickable(true);
mRatingBar.setStarImageWidth(120f);
mRatingBar.setStarImageHeight(60f);
mRatingBar.setImagePadding(35);
mRatingBar.setOnRatingChangeListener(
new RatingBar.OnRatingChangeListener() {
@Override
public void onRatingChange(float RatingCount) {
Toast.makeText(MainActivity.this, "the fill star is" + RatingCount, Toast.LENGTH_SHORT).show();
}
}
);
}
}
参考地址:自定义RatingBar