Skip to content

Instantly share code, notes, and snippets.

@HKhademian
Created February 11, 2016 22:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HKhademian/6ccc85db23b8745dc4c4 to your computer and use it in GitHub Desktop.
Save HKhademian/6ccc85db23b8745dc4c4 to your computer and use it in GitHub Desktop.
A simple Android Rating View that extends LinearLayout and fill it with ImageViews
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