English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Implementierung des XiuYiXiu-Effekts von Alipay durch Android- benutzerdefinierte Views

This article introduces how to implement the following effects using a custom View and property animation

The implementation idea is quite simple:

  • Draw a semi-transparent circle
  • Implement two animation effects, expanding when clicked and retracting when not clicked
  • Combine the above two steps using a thread

First, let's look at the part of drawing a semi-transparent circle

public class ClickCircleView extends View {
 private Bitmap bitmap;
 private Paint paint;
 private Canvas canvas;
 private boolean isSpreadFlag = false;//Mark whether the emission is completed
 public boolean isSpreadFlag() {
  return isSpreadFlag;
 }
 public void setIsSpreadFlag(boolean isSpreadFlag) {
  this.isSpreadFlag = isSpreadFlag;
 }
 public ClickCircleView(Context context, int width, int height, int screenWidth, int screenHeight) {
  super(context);
  bitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888); // Bitmapgröße und -breite einstellen
  canvas = new Canvas();
  canvas.setBitmap(bitmap);
  paint = new Paint(Paint.DITHER_FLAG);
  paint.setAntiAlias(true);
  paint.setColor(Color.WHITE);
  paint.setStyle(Paint.Style.FILL);
  paint.setAlpha(50);
  canvas.drawCircle(screenWidth / 2, screenHeight / 2, width / 2 + 10, paint);
  invalidate();
 }
 @Override
 protected void onDraw(Canvas canvas) {
  canvas.drawBitmap(bitmap, 0, 0, null);
 }
}

Man kann sehen, dass alle zugehörigen Eigenschaften auf dem Stift eingestellt sind, dann wird direkt das drawCircle()-Verfahren des Canvas aufgerufen, um einen halbtransparenten Kreis zu zeichnen, und schließlich wird invalidate() aufgerufen, um die View zu aktualisieren
Es muss unbedingt die Methode onDraw() der Oberklasse überschrieben werden, sonst funktioniert die benutzerdefinierte View nicht
Wir haben einen Flaggeis SpreadFlag eingerichtet, deren Zweck es ist, anzuzeigen, ob die Verbreitung und -sammelanimation abgeschlossen ist

Dann implementieren wir zwei Animationseffekte

Klickverbreitung und -sammelanimation

<set xmlns:android="http://schemas.android.com/apk/res/android">
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleY"
  android:valueFrom="1.0"
  android:valueTo="1.8"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleX"
  android:valueFrom="1.0"
  android:valueTo="1.8"
  android:valueType="floatType" />
</set>

Es ist sehr einfach, den Scale-Wert zu ändern und zu vergrößern1.8mal

Keine Klickverbreitung und -sammelanimation

<set xmlns:android="http://schemas.android.com/apk/res/android"
 android:ordering="together">
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleX"
  android:valueFrom="1.0"
  android:valueTo="1.2"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleY"
  android:valueFrom="1.0"
  android:valueTo="1.2"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleX"
  android:startOffset="10"00"
  android:valueFrom="1.2"
  android:valueTo="1.0"
  android:valueType="floatType" />
 <objectAnimator
  android:duration="10"00"
  android:propertyName="scaleY"
  android:startOffset="10"00"
  android:valueFrom="1.2"
  android:valueTo="1.0"
  android:valueType="floatType" />
</set>

和上个动画类似,startOffset参数可以用来控制Animation的运行顺序,比如Android:startOffset="10"00"表示设置该属性的动画延迟1秒执行

然后就是用线程来执行动画和逻辑的部分了

不点击时的动画部分

mXiuyixiuButton.post(new Runnable() {
   @Override
   public void run() {
    clickCircleView = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth()
      , mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getMeasuredWidth(),
      mXiuyixiuLayout.getMeasuredHeight());
    clickCircleView.setVisibility(View.VISIBLE);
    mXiuyixiuLayout.addView(clickCircleView);
    mXiuyixiuLayout.postInvalidate();
    // 加载动画
    final Animator anim = AnimatorInflater.loadAnimator(CustomView1.this,
      R.animator.circle_scale_animator);
    anim.addListener(new AnimatorListenerAdapter() {
     @Override
     public void onAnimationEnd(Animator animation) {
      if (anim != null) {
       anim.start();//循环执行动画
      }
     }
    });
    anim.setTarget(clickCircleView);
    anim.start();
   }
  });

初始化好clickCircleView之后将这个view加入父布局中,然后加载动画并设置循环执行,最后使用postInvalidate()在子线程中刷新view

点击时的动画部分

mXiuyixiuButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    clickCircleView.setVisibility(View.GONE);//发射圆圈,即将循环动画View隐藏
    final ClickCircleView item = new ClickCircleView(CustomView1.this, mXiuyixiuButton.getWidth()
      , mXiuyixiuButton.getHeight(), mXiuyixiuLayout.getWidth(),
      mXiuyixiuLayout.getHeight());
    Animator spreadAnim = AnimatorInflater.loadAnimator(CustomView1.this,
      R.animator.circle_spread_animator);
    spreadAnim.addListener(new AnimatorListenerAdapter() {
     @Override
     public void onAnimationEnd(Animator animation) {
      item.setIsSpreadFlag(true);//Markiere, dass die Animation abgeschlossen ist
     }
    });
    spreadAnim.setTarget(item);
    spreadAnim.start();
    clickCircleViewList.add(item);
    mXiuyixiuLayout.addView(item);
    mXiuyixiuLayout.invalidate();
    handler.post(circleViewRunnable);
   }
  });


Verstecke die Animation, die nicht angeklickt wird, füge den ClickCircleView nach der Initialisierung der View zur Liste hinzu und füge ihn dem Eltern-Layout hinzu, läade dann die Animation und füge am Ende der Animation den isSpreadFlag-Tag hinzu, rufe schließlich invalidate() auf, um die View zu aktualisieren und starte den Thread

Thread-Teil

private Runnable circleViewRunnable = new Runnable() {
  public void run() {
   for (int i = 0; i < clickCircleViewList.size(); i++) {
    if (clickCircleViewList.get(i).isSpreadFlag()) {
     mXiuyixiuLayout.removeView(clickCircleViewList.get(i));
     clickCircleViewList.remove(i);
     mXiuyixiuLayout.postInvalidate();
    }
   }
   if (clickCircleViewList.size() <= 0) {
    clickCircleView.setVisibility(View.VISIBLE);
   }
   handler.postDelayed(this, 100);
  }
 };

Durchsuchen Sie die Liste, entfernen Sie die mit dem isSpreadFlag markierten Views aus der Liste und dem übergeordneten Layout, aktualisieren Sie das View, und zeigen Sie am Ende, wenn die Liste leer ist, die Animation ohne Klick an

Denken Sie daran, den Thread in onDestroy() zu entfernen

@Override
 geschützt void onDestroy() {
  super.onDestroy();
  handler.removeCallbacks(circleViewRunnable);
 }

Die Implementierung dieses Effekts erfordert eine starke Kopplung mit benutzerdefinierten Views und Animationseigenschaften, ist jedoch im Vergleich zur vollständigen Verwendung von benutzerdefinierten Views flüssiger. Die meisten Codes werden aus anderen Blogs entnommen, aber wenn man sie nur so verwendet und nicht zusammenfasst, wird es nicht zu eigenen Kenntnissen. Daher dieses Blog.

Referenz: Mehrere Ansätze und Methoden zur Implementierung von Alipay Xiuyuxiu in Android

Das ist der gesamte Inhalt dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und dass Sie die Anleitung von Rufen stark unterstützen.

Erklärung: Dieser Artikel wurde aus dem Internet übernommen und gehört dem Urheberrechtsinhaber. Der Inhalt wurde von Internetbenutzern selbstständig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine rechtlichen Verantwortlichkeiten. Wenn Sie verdächtige Urheberrechtsinhalte finden, sind Sie herzlich eingeladen, eine E-Mail an: notice#w zu senden.3Anzeige: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem Urheberrechtsinhaber. Der Inhalt wurde von Internetbenutzern selbstständig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine rechtlichen Verantwortlichkeiten. Wenn Sie verdächtige Urheberrechtsinhalte finden, senden Sie bitte eine E-Mail an: notice#w

Empfohlene Artikel