A simple Android Rating View that extends LinearLayout and fill it with ImageViews
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package hco.widget; | |
import android.content.Context; | |
import android.graphics.Color; | |
import android.graphics.drawable.Drawable; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.ImageView; | |
import android.widget.LinearLayout; | |
import hco.tools.SimplePool; | |
import static android.view.Gravity.CENTER; | |
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; | |
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; | |
import static hco.utils.Uis.dp2px; | |
import static java.lang.Math.max; | |
import static java.lang.Math.min; | |
import static java.lang.Math.round; | |
public class RatingView extends LinearLayout { | |
private Drawable starEmptyDrawable; | |
private Drawable starFillDrawable; | |
private Drawable starHalfDrawable; | |
private int starImageSize = WRAP_CONTENT; // size<=0 (+ WRAP or MATH): add weight to star view | |
private boolean clickable = true; | |
private float rate = 0; | |
private OnRatingChangeListener onRatingChangeListener; | |
/** this simple pool I write from base you can use what pool you want */ | |
private final SimplePool<ImageView> starViewPool = new SimplePool<ImageView>() { | |
private final OnClickListener onClickListener = new OnClickListener() { | |
@Override | |
public void onClick(final View v) { | |
if (clickable) { | |
final int rate = RatingView.super.indexOfChild(v) + 1; | |
setRate(rate); | |
if (onRatingChangeListener != null) | |
onRatingChangeListener.onRatingChange(rate); | |
} | |
} | |
}; | |
@Override | |
public ImageView newObject(final Object... params) { | |
final ImageView item = new ImageView(getContext()); | |
item.setLayoutParams(new ViewGroup.LayoutParams(starImageSize, MATCH_PARENT)); | |
item.setPadding(0, 0, dp2px(2), 0); | |
item.setImageDrawable(starEmptyDrawable); | |
item.setOnClickListener(onClickListener); | |
item.setAdjustViewBounds(true); | |
item.setBackgroundColor(Color.RED); | |
return item; | |
} | |
@Override | |
protected void init(final ImageView item, final Object... params) { | |
final LayoutParams layoutParams = item.getLayoutParams() instanceof LayoutParams ? (LayoutParams) item.getLayoutParams() : new LayoutParams(0, 0); | |
layoutParams.width = starImageSize; | |
layoutParams.height = MATCH_PARENT; | |
layoutParams.weight = starImageSize > 0 ? 0 : 1; | |
item.setLayoutParams(layoutParams); | |
} | |
}; | |
public RatingView(final Context context, final int starCount) { | |
super(context); | |
super.setGravity(CENTER); | |
super.setOrientation(HORIZONTAL); | |
super.setBackgroundColor(Color.BLACK); | |
setStarCount(starCount); | |
} | |
/** I hate android xml based views */ | |
public RatingView(final Context context) { | |
this(context, 5); | |
} | |
public void setStarHalfDrawable(final Drawable starHalfDrawable) { | |
this.starHalfDrawable = starHalfDrawable; | |
} | |
public void setOnRatingChangeListener(final OnRatingChangeListener onRatingChangeListener) { | |
this.onRatingChangeListener = onRatingChangeListener; | |
} | |
public void setClickable(final boolean clickable) { | |
this.clickable = clickable; | |
} | |
public void setStarFillDrawable(final Drawable starFillDrawable) { | |
this.starFillDrawable = starFillDrawable; | |
} | |
public void setStarEmptyDrawable(final Drawable starEmptyDrawable) { | |
this.starEmptyDrawable = starEmptyDrawable; | |
} | |
public void setStarImageSize(final int starImageSize) { | |
this.starImageSize = starImageSize; | |
} | |
public void setStarCount(final int starCount) { | |
if (super.getChildCount() == starCount) | |
return; | |
for (int i = 0; i < super.getChildCount(); i++) | |
try { | |
starViewPool.recycle((ImageView) getChildAt(i)); | |
} catch (final Throwable e) { | |
e.printStackTrace(); | |
} | |
super.removeAllViews(); | |
for (int i = 0; i < starCount; i++) | |
super.addView(starViewPool.get()); | |
setRate(); | |
} | |
public void setRate(float rate) { | |
final int starCount = super.getChildCount(); | |
this.rate = rate = max(0, min(starCount, rate)); // [0,starCount] | |
final int stars = round(rate); | |
final boolean half = rate > stars; // x.y shows x.5 | |
for (int i = 0; i < starCount; ++i) | |
((ImageView) getChildAt(i)).setImageDrawable(i <= stars ? starFillDrawable : starEmptyDrawable); | |
if (half) | |
((ImageView) getChildAt(stars)).setImageDrawable(starHalfDrawable); | |
} | |
/** refresh rating */ | |
public void setRate() { | |
setRate(rate); | |
} | |
/** change stat listener */ | |
public interface OnRatingChangeListener { | |
void onRatingChange(final int RatingCount); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment