先看效果图:
分析:两张图片,一张默认 一张选中图片
使用 canvas.drawBitmap()
跟之前有不同地方是:资源属性是一张图片 在自定义的view的时候 要采用bitmap的方式,通过BitmapFactory来加载资源文件。
获取资源属性代码:
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StarView);
mStarCount = typedArray.getInt(R.styleable.StarView_starCount,mStarCount);
mStarMargin = (int)typedArray.getDimension(R.styleable.StarView_starMargin,mStarMargin);
int mStarNormalId = typedArray.getResourceId(R.styleable.StarView_starNormal, 0);
if(mStarNormalId ==0){
throw new RuntimeException("请先设置属性");
}
int mStarFocusId = typedArray.getResourceId(R.styleable.StarView_starFocus,0);
if(mStarFocusId ==0){
throw new RuntimeException("请先设置属性");
}
mStarNormalBitmap = BitmapFactory.decodeResource(getResources(), mStarNormalId);
mStarFocusBitmap = BitmapFactory.decodeResource(getResources(),mStarFocusId);
typedArray.recycle();
重写OnDraw()方法
for(int i=0;i<mStarCount ; i ++ ) {
int width =mStarNormalBitmap.getWidth() * i + getPaddingLeft() + i *mStarMargin;
canvas.drawBitmap(mStarNormalBitmap,width,0,null);
if(mStarFocusCount > i){
canvas.drawBitmap(mStarFocusBitmap,width,0,null);
}
}
重写onMeasure()方法计算宽高 注意padding问题
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width =mStarNormalBitmap.getWidth();
//高度 为 图片的高度 宽度为 图片数量乘以图片宽度
width = (mStarCount-1) *mStarMargin + getPaddingLeft() + getPaddingRight() + width *mStarCount;
int height =mStarNormalBitmap.getHeight() + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(width,height);
}
还要重写 onTouchEvent() 才能够实现滑动的效果:
重写onTouchEvent事件的时候 要返回true 否则无法滑动 为什么呢?后面会有笔记
只需要考虑 x 抽的问题就行
float x1 = event.getX();
doUpdate(x1);
private void doUpdate(float downX){
if(0 < downX && downX < getWidth()){
downX = downX - getPaddingLeft();
if(downX <=0){
mStarFocusCount =0;
}else {
int bx =mStarNormalBitmap.getWidth() +mStarMargin;
int a = (int)( downX / bx );
Log.d("TAG=>结果",a+"");
mStarFocusCount = a +1;
}
invalidate();
}
}
以上代码存在内存需要优化的问题,请大家注意:每次滑动都会不断的调用onDraw()方法
应该是在星星范围内才滑动才好
if(count !=mStarFocusCount){
mStarFocusCount = count;
invalidate();
}
好了,源码地址: