android 仿微信表情雨下落!

taixiang 2018-09-09 原文

android 仿微信表情雨下落!

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

众所周知,微信聊天中我们输入一些关键词会有表情雨下落,比如输入「生日快乐」「么么哒」会有相应的蛋糕、亲吻的表情雨下落,今天就来完成这个表情雨下落的效果。
先来看下效果,真·狗头雨·落!

确认表情的模型,定义属性

public class ItemEmoje {
    //坐标
    public int x;
    public int y;
    // 横向偏移
    public int offsetX;
    //纵向偏移
    public int offsetY;
    //缩放
    public float scale;
    //图片资源
    public Bitmap bitmap;
}

自定义RainView 表情下落视图,初始化变量。

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<>();
    }
}

初始化表情雨数据,确认每个表情的起始位置,下落过程中横向、纵向的偏移,以及缩放大小。

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() 方法触发。

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

布局文件

<?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_emoji

欢迎关注我的博客:https://www.manjiexiang.cn/

更多精彩欢迎关注微信号:春风十里不如认识你
一起学习,一起进步,有问题随时联系,一起解决!!!

发表于 2018-09-09 17:49 程序猿tx 阅读() 评论() 编辑 收藏

 

版权声明:本文为taixiang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/taixiang/p/9614380.html

android 仿微信表情雨下落!的更多相关文章

  1. Android Studio入门(安装–>开发调试)

    <div id=”zmdao_post_body” class=”b […]...

  2. Android 图标尺寸设计要求官方地址

    http://developer.android.com/design/style/iconography.h […]...

  3. Flutter 开发从 0 到 1(四)ListView 下拉加载和加载更多

    在《APP 开发从 0 到 1(三)布局与 ListView》我们完成了 ListView,这篇文章将做 Li […]...

  4. 面试 5:手写 Java 的 pow() 实现

    我们在处理一道编程面试题的时候,通常除了注意代码规范以外,千万要记得自己心中模拟一个单元测试。主要通过三方面来 […]...

  5. android 图片叠加效果——两种方法

    android 图片叠加效果——两种方法 效果图: 第一种: 第二种:   第一种是通过canvas画出来的效 […]...

  6. Android 获取联系人手机号码、姓名、地址、公司、邮箱、生日

    public void testGetAllContact() throws Throwable { //获取 […]...

  7. 2020年Android开发最新整理阿里巴巴、字节跳动、小米面经,你不看看吗?

    前言 2020年是转折的一年,上半年疫情原因,很多学android开发的小伙伴失业了,虽找到了一份工作,但高不 […]...

  8. Android 应用程序集成Google 登录及二次封装 – Sun‘刺眼的博客

    Android 应用程序集成Google 登录及二次封装 谷歌登录API:  https://develope […]...

随机推荐

  1. vue项目中编写一个图片预览的公用组件

    vue项目中编写一个图片预览的公用组件 今天产品提出了一个查看影像的功能需求。 在查看单据的列表中,有一列是影 […]...

  2. 每日站会怎么开才好?——你的站会姿势正确吗?

    今天我们讲讲如何利用站会,更好地实现促进团队有效协作和聚焦,促进价值顺畅流动和交付,同时及时的暴露问题和风险。 […]...

  3. shell编程入门-适合小白

    一、变量的使用 1. 变量命名 定义变量时,变量名不加美元符号($,PHP语言中变量需要),如: your_n […]...

  4. IDEA配置jQuery,$符号不再显示黄色波浪线

    在使用IDEA搭建Maven的Web环境时,编写的JQuery入口函数时,遇到了未知符号的提示,并且在前端页面 […]...

  5. 扩展欧几里得求解的个数

    知识储备 扩展欧几里得定理 欧几里得定理 (未掌握的话请移步扩展欧几里得) 正题 设存在\(ax+by=gcd […]...

  6. ubuntu使用教程

    Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音。了解发音是 […]...

  7. 你的google adsense为什么被禁止,如何恢复?

    1、自己点击站上广告,此行为被誉为“无效点击”。Google政策原文:“我们不容许您因任何原因点击自己网站上的 […]...

  8. Spring AOP系列(五)—反射

    前言 前面我们进行了代理模式、静态代理、动态代理的学习。而动态代理就是利用Java的反射技术(Java Ref […]...

展开目录

目录导航