android 仿微信表情雨下落!

文章連接: https://mp.weixin.qq.com/s/yQXn-YjEFSW1X7A7CcuaVg

衆所周知,微信聊天中咱們輸入一些關鍵詞會有表情雨下落,好比輸入「生日快樂」「麼麼噠」會有相應的蛋糕、親吻的表情雨下落,今天就來完成這個表情雨下落的效果。
先來看下效果,真·狗頭雨·落! android

確認表情的模型,定義屬性git

public class ItemEmoje {
    //座標
    public int x;
    public int y;
    // 橫向偏移
    public int offsetX;
    //縱向偏移
    public int offsetY;
    //縮放
    public float scale;
    //圖片資源
    public Bitmap bitmap;
}

自定義RainView 表情下落視圖,初始化變量。github

public class RainView extends View {
    private Paint paint;
    //圖片處理
    private Matrix matrix;
    private Random random;
    //判斷是否運行的,默認沒有
    private boolean isRun;
    //表情包集合
    private List<ItemEmoje> bitmapList;
    //表情圖片
    private int imgResId = R.mipmap.dog;

    public RainView(Context context) {
        this(context, null);
    }

    public RainView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RainView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        matrix = new Matrix();
        random = new Random();
        bitmapList = new ArrayList<>();
    }
}

初始化表情雨數據,確認每一個表情的起始位置,下落過程當中橫向、縱向的偏移,以及縮放大小。canvas

private void initData() {
    for (int i = 0; i < 20; i++) {
        ItemEmoje itemEmoje = new ItemEmoje();
        itemEmoje.bitmap = BitmapFactory.decodeResource(getResources(), imgResId);
        //起始橫座標在[100,getWidth()-100) 之間
        itemEmoje.x = random.nextInt(getWidth() - 200) + 100;
        //起始縱座標在(-getHeight(),0] 之間,即一開始位於屏幕上方之外
        itemEmoje.y = -random.nextInt(getHeight());
        //橫向偏移[-2,2) ,即左右搖擺區間
        itemEmoje.offsetX = random.nextInt(4) - 2;
        //縱向固定下落12
        itemEmoje.offsetY = 12;
        //縮放比例[0.8,1.2) 之間
        itemEmoje.scale = (float) (random.nextInt(40) + 80) / 100f;
        bitmapList.add(itemEmoje);
    }
}

下落過程經過 onDraw進行繪製,不斷的計算橫縱座標,達到下落效果。微信

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (isRun) {
        //用於判斷表情下落結束,結束即再也不進行重繪
        boolean isInScreen = false;
        for (int i = 0; i < bitmapList.size(); i++) {
            matrix.reset();
            //縮放
            matrix.setScale(bitmapList.get(i).scale, bitmapList.get(i).scale);
            //下落過程座標
            bitmapList.get(i).x = bitmapList.get(i).x + bitmapList.get(i).offsetX;
            bitmapList.get(i).y = bitmapList.get(i).y + bitmapList.get(i).offsetY;
            if (bitmapList.get(i).y <= getHeight()) {//當表情仍在視圖內,則繼續重繪
                isInScreen = true;
            }
            //位移
            matrix.postTranslate(bitmapList.get(i).x, bitmapList.get(i).y);
            canvas.drawBitmap(bitmapList.get(i).bitmap, matrix, paint);
        }
        if (isInScreen) {
            postInvalidate();
        }else {
            release();
        }
    }
}

/**
 *釋放資源
 */
private void release(){
    if(bitmapList != null && bitmapList.size()>0){
        for(ItemEmoje itemEmoje : bitmapList){
            if(!itemEmoje.bitmap.isRecycled()){
                itemEmoje.bitmap.recycle();
            }
        }
        bitmapList.clear();
    }
}

提供start() 方法觸發。dom

public void start(boolean isRun) {
    this.isRun = isRun;
    initData();
    postInvalidate();
}

佈局文件ide

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.rain.RainView
        android:id="@+id/testView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <Button
        android:id="@+id/btn_dog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="真·狗頭雨·落!" />

    <Button
        android:id="@+id/btn_cake"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginLeft="10dp"
        android:layout_toRightOf="@+id/btn_dog"
        android:text="蛋糕雨" />

</RelativeLayout>

activity 點擊事件觸發佈局

btnCake.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //蛋糕圖片
        rainView.setImgResId(R.mipmap.cake);
        rainView.start(true);
    }
});
btnDog.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //狗頭圖片
        rainView.setImgResId(R.mipmap.dog);
        rainView.start(true);
    }
});

github地址:https://github.com/taixiang/rain_emojipost

歡迎關注個人博客:https://www.manjiexiang.cn/ 學習

更多精彩歡迎關注微信號:春風十里不如認識你
一塊兒學習,一塊兒進步,有問題隨時聯繫,一塊兒解決!!!

相關文章
相關標籤/搜索