English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
This article introduces how to implement the following effects using a custom View and property animation
The implementation idea is quite simple:
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