package com.wiseandroid.samples.mvcdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public final class StarRatingView extends View implements StarRatingModel.Listener {
private StarRatingModel model;
private StarRatingController controller;
private float starSize;
private PointF starTopLeft = new PointF();
private RectF starRect = new RectF();
private Bitmap starBitmap;
private Paint goldPaint;
private Paint grayPaint;
public StarRatingView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public StarRatingView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public StarRatingView(Context context) {
super(context);
init();
}
private void init() {
starBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.star);
goldPaint = new Paint();
goldPaint.setFilterBitmap(true);
grayPaint = new Paint();
grayPaint.setColorFilter(new LightingColorFilter(0xff111122, 0xffcccccc));
grayPaint.setFilterBitmap(true);
setModel(new StarRatingModel());
}
@Override
protected void onDraw(Canvas canvas) {
for (int i = 0; i < StarRatingModel.MAX_STARS; ++i) {
float starX = starTopLeft.x + i * starSize;
float starY = starTopLeft.y;
Paint paint = null;
if ((i + 1) <= model.getStars()) {
// draw a gold star
paint = goldPaint;
} else {
// draw a gray star
paint = grayPaint;
}
starRect.set(starX, starY, starX + starSize, starY + starSize);
canvas.drawBitmap(starBitmap, null, starRect, paint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
widthSize = 30 * StarRatingModel.MAX_STARS;
}
int width = widthSize;
int height = heightSize;
if (heightMode != MeasureSpec.EXACTLY) {
height = width / StarRatingModel.MAX_STARS;
}
setMeasuredDimension(width, height);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// We have to fit as much as MAX_STARS into the space we have
starSize = Math.min(h, ((float) w) / StarRatingModel.MAX_STARS);
starTopLeft.x = (w - starSize * StarRatingModel.MAX_STARS) / 2;
starTopLeft.y = (h - starSize) / 2;
}
public void setModel(StarRatingModel model) {
if (model == null) {
throw new NullPointerException("model");
}
StarRatingModel oldModel = this.model;
if (oldModel != null) {
oldModel.removeListener(this);
}
this.model = model;
this.model.addListener(this);
this.controller = new StarRatingController(this.model);
if (oldModel != null) {
invalidate();
}
}
public StarRatingModel getModel() {
return model;
}
@Override
public void handleStarRatingChanged(StarRatingModel sender) {
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
controller.handleTap(event);
return true;
} else {
return super.onTouchEvent(event);
}
}
}
评论30