自定义斗鱼礼物动画

项目需求,仿着斗鱼做了个自定义礼物的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的一个小应用,对应的资源大家自己找美工吧~

程序员内功修炼手册 不定期分享程序员基础知识,大前端知识!想跟博主一块成长的快快关注吧!

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值