项目需求,仿着斗鱼做了个自定义礼物的view,绘制图片实现,
效果大概就是这样:
直接上代码
<declare-styleable name="GiftView">
<attr name="giftDrawable" format="reference"/><!--礼物图片资源id-->
<attr name="xDrawable" format="reference"/><!--乘号图片资源id-->
<attr name="numbers" format="integer"/><!--礼物数量-->
</declare-styleable>
自定义view
/**
* Created by yinw on 2016-12-08.
* 自定义礼物view
*/
public class GiftView extends View {
private int mGiftId, mXId, numbers, maxNumber, measureHeight, measureWidth;
private Paint paint;
private Bitmap mGift, mX;
private boolean isFirstLayout = true,withAni = false;
private int levelSize = 0;//绘制图片的大小等级
private final int CHANGESIZE=10;//变更的大小
public GiftView(Context context) {
this(context, null);
}
public GiftView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GiftView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.GiftView, defStyleAttr, 0);
mGiftId = typedArray.getResourceId(R.styleable.GiftView_giftDrawable, -1);
mXId = typedArray.getResourceId(R.styleable.GiftView_xDrawable, -1);
numbers = typedArray.getInt(R.styleable.GiftView_numbers, -1);
typedArray.recycle();
initGiftAndX();
maxNumber = numbers;
paint = new Paint();
}
private void initGiftAndX() {
if (mXId != -1) {
mX = ((BitmapDrawable) getResources().getDrawable(mXId)).getBitmap();
}
if (mGiftId != -1) {
mGift = ((BitmapDrawable) getResources().getDrawable(mGiftId)).getBitmap();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
measureHeight = MeasureSpec.getSize(heightMeasureSpec);
measureWidth = MeasureSpec.getSize(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
if (mGift != null) {
measureWidth = mGift.getWidth();
}
if (mX != null) {
measureWidth += mX.getWidth();
}
if (maxNumber != -1) {
measureWidth += getNumbersWidth(maxNumber);//按照最大数字
}
measureWidth += (getPaddingLeft() + getPaddingRight());
}
if (heightMode != MeasureSpec.EXACTLY) {
if (mGift != null) {
measureHeight = mGift.getHeight();
}
measureHeight += (getPaddingTop() + getPaddingBottom());
}
setMeasuredDimension(measureWidth, measureHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mGift != null && mX != null && numbers != -1) {
drawNumbers(canvas, numbers, drawGiftAndX(canvas));
//只调用一次,以防影响性能
if (isFirstLayout) {
requestLayout();//重新计算宽高重新布局
isFirstLayout = false;
}
}
}
/**
*
* @param mGiftId 礼物资源id
* @param mXId 乘号资源id
* @param numbers 数字大小
* @param withAni 是否数字递增造成动画效果还是直接绘制数字
*/
public void setGiftSettings(int mGiftId, int mXId, final int numbers, boolean withAni) {
this.mGiftId = mGiftId;
this.mXId = mXId;
this.numbers = numbers;
this.maxNumber = numbers;
this.withAni = withAni;
initGiftAndX();
if (withAni) {
new Thread(new Runnable() {
@Override
public void run() {
GiftView.this.numbers = 0;//改变数字的大小,通过重绘制造动画效果
while (GiftView.this.numbers < numbers) {
//数字变回本来大小
if (levelSize == 0) {
GiftView.this.numbers++;
}
postInvalidate();
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return;
}
invalidate();
}
//绘制礼物和符号
private int drawGiftAndX(Canvas canvas) {
int gXWidth = 0;
if (mGift != null) {
canvas.drawBitmap(mGift, getPaddingLeft(), getPaddingTop(), paint);
gXWidth = mGift.getWidth() + getPaddingLeft();
}
Bitmap NMx=mX;
if (mX != null) {
if (withAni) {
if (levelSize == 0) {
levelSize = 1;
} else {
levelSize = 0;
}
if(levelSize==1) {
NMx = Bitmap.createScaledBitmap(NMx, NMx.getWidth() + CHANGESIZE, NMx.getHeight() + CHANGESIZE, false);//图片增大
}
}
canvas.drawBitmap(NMx, gXWidth, (mGift.getHeight() - NMx.getHeight()) / 2 + getPaddingTop(), paint);
gXWidth += NMx.getWidth();
}
return gXWidth;
}
//绘制出数字图片
private void drawNumbers(Canvas canvas, int numbers, int beginX) {
String number = String.valueOf(numbers);
int width = beginX;
Bitmap bitmap;
for (int i = 1; i <= number.length(); i++) {
bitmap = resolveNumber(Integer.parseInt(number.substring(i - 1, i)));
if (withAni) {
if (levelSize == 1) {
bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() + CHANGESIZE, bitmap.getHeight() + CHANGESIZE, false);//图片增大
}
}
canvas.drawBitmap(bitmap, width, (mGift.getHeight() - bitmap.getHeight()) / 2 + getPaddingTop(), paint);
width += bitmap.getWidth();
}
}
//解析出数字对应的资源图片id,这里并没有对图片进行防溢出处理,因为图片本身都很小,自己注意就行,以上也是
private Bitmap resolveNumber(int number) {
Bitmap numBitmap = null;
switch (number) {
case 0:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num0)).getBitmap();
break;
case 1:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num1)).getBitmap();
break;
case 2:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num2)).getBitmap();
break;
case 3:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num3)).getBitmap();
break;
case 4:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num4)).getBitmap();
break;
case 5:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num5)).getBitmap();
break;
case 6:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num6)).getBitmap();
break;
case 7:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num7)).getBitmap();
break;
case 8:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num8)).getBitmap();
break;
case 9:
numBitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.num9)).getBitmap();
break;
}
return numBitmap;
}
//计算数字长度
private int getNumbersWidth(int numbers) {
int width = 0;
String number = String.valueOf(numbers);
for (int i = 1; i <= number.length(); i++) {
width += (resolveNumber(Integer.parseInt(number.substring(i - 1, i))).getWidth() + CHANGESIZE);
}
return width;
}
}
这里主要是对bitmap的一个小应用,对应的资源大家自己找美工吧~
程序员内功修炼手册 不定期分享程序员基础知识,大前端知识!想跟博主一块成长的快快关注吧!