java实现物体下落效果_android仿微信表情雨下落效果的实现方法

本文介绍了如何使用Java在Android平台上实现类似微信聊天中的表情雨下落效果。通过创建自定义RainView,设置表情模型的属性,并在onDraw方法中更新坐标,实现了动态下落的视觉效果。读者可以通过点击按钮切换不同表情,如狗头和蛋糕。
摘要由CSDN通过智能技术生成

前言

众所周知,微信聊天中我们输入一些关键词会有表情雨下落,比如输入「生日快乐」「么么哒」会有相应的蛋糕、亲吻的表情雨下落,今天就来完成这个表情雨下落的效果。下面话不多说了,来一起看看详细的介绍吧

效果图

先来看下效果,真·狗头雨·落!

19e69b554618051565ad3f8ac03bbfa9.gif

实现代码

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

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

}

布局文件

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/testView"

android:layout_width="match_parent"

android:layout_height="match_parent" />

android:id="@+id/btn_dog"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:text="真·狗头雨·落!" />

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="蛋糕雨" />

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

}

});

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值