溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

android仿微信表情雨下落效果的實(shí)現(xiàn)方法

發(fā)布時(shí)間:2020-09-06 03:34:12 來(lái)源:腳本之家 閱讀:216 作者:程序猿tx 欄目:移動(dòng)開(kāi)發(fā)

前言

眾所周知,微信聊天中我們輸入一些關(guān)鍵詞會(huì)有表情雨下落,比如輸入「生日快樂(lè)」「么么噠」會(huì)有相應(yīng)的蛋糕、親吻的表情雨下落,今天就來(lái)完成這個(gè)表情雨下落的效果。下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧

效果圖

先來(lái)看下效果,真·狗頭雨·落!

android仿微信表情雨下落效果的實(shí)現(xiàn)方法

實(shí)現(xiàn)代碼

確認(rèn)表情的模型,定義屬性

public class ItemEmoje {
 //坐標(biāo)
 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;
 //判斷是否運(yùn)行的,默認(rèn)沒(méi)有
 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<>();
 }
}

初始化表情雨數(shù)據(jù),確認(rèn)每個(gè)表情的起始位置,下落過(guò)程中橫向、縱向的偏移,以及縮放大小。

private void initData() {
 for (int i = 0; i < 20; i++) {
 ItemEmoje itemEmoje = new ItemEmoje();
 itemEmoje.bitmap = BitmapFactory.decodeResource(getResources(), imgResId);
 //起始橫坐標(biāo)在[100,getWidth()-100) 之間
 itemEmoje.x = random.nextInt(getWidth() - 200) + 100;
 //起始縱坐標(biāo)在(-getHeight(),0] 之間,即一開(kāi)始位于屏幕上方以外
 itemEmoje.y = -random.nextInt(getHeight());
 //橫向偏移[-2,2) ,即左右搖擺區(qū)間
 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);
 }
}

下落過(guò)程通過(guò) onDraw進(jìn)行繪制,不斷的計(jì)算橫縱坐標(biāo),達(dá)到下落效果。

@Override
protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 if (isRun) {
 //用于判斷表情下落結(jié)束,結(jié)束即不再進(jìn)行重繪
 boolean isInScreen = false;
 for (int i = 0; i < bitmapList.size(); i++) {
  matrix.reset();
  //縮放
  matrix.setScale(bitmapList.get(i).scale, bitmapList.get(i).scale);
  //下落過(guò)程坐標(biāo)
  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()) {//當(dāng)表情仍在視圖內(nèi),則繼續(xù)重繪
  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() 方法觸發(fā)。

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 點(diǎn)擊事件觸發(fā)

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 (本地下載)

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI