English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
この記事では、カスタムViewと属性アニメーションを使用して以下のような効果を実現する方法を紹介します
実現方法は非常にシンプルです:
まず半透明円の描画部分を見てみましょう
public class ClickCircleView extends View { private Bitmap bitmap; private Paint paint; private Canvas canvas; private boolean isSpreadFlag = false;//マークが発射完了かどうかを示します 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); // ビットマップの幅と高さを設定する 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); } }
関連する属性はすべてペンに設定されており、次にキャンバスのdrawCircle()メソッドを直接呼び出して半透明の円を描画し、最後にinvalidate()メソッドを呼び出してビューを更新します
絶対に親クラスのonDraw()メソッドをオーバーライドする必要があります。さもなければ、カスタムビューは有効になりません
isSpreadFlagというフラグを設定し、拡散アニメーションが完了したかどうかをマークする役割があります
次に、2つのアニメーション効果を実現するために
タップ時に拡散されるアニメーション
<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>
非常に単純で、scale値を変更し、拡大して1.8倍
タップしないと拡散されるアニメーション
<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);//アニメーションが完了したら、マークを付けます } }); spreadAnim.setTarget(item); spreadAnim.start(); clickCircleViewList.add(item); mXiuyixiuLayout.addView(item); mXiuyixiuLayout.invalidate(); handler.post(circleViewRunnable); } });
非クリックアニメーションを隠し、ClickCircleViewを初期化し、リストに追加し、親レイアウトに追加し、アニメーションをロードし、アニメーション終了時にisSpreadFlagマークを追加し、最後にinvalidate()メソッドを呼び出してビューをリフレッシュし、スレッドを開始します
スレッド部分
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); } };
リストをループし、isSpreadFlagマークがあるビューをリストと親レイアウトから削除し、ビューをリフレッシュし、リストが空であれば、非クリック時のアニメーションを表示するようにします。
最後に、onDestroy()内でスレッドを削除することを忘れないでください。
@Override protected void onDestroy() { super.onDestroy(); handler.removeCallbacks(circleViewRunnable); }
カスタムビューと属性アニメーションを組み合わせてこの効果を実現することで、コードの耦合性が高くなりますが、完全にカスタムビューを使用するよりもより滑らかです。この方法はほとんどが他のブログのコードを参照して実現されていますが、ただ単に使ってまとめずには知識にはなりませんので、このブログを作成しました。
参照: androidの支付宝スウィッシュのいくつかの実現方法と思考
これでこの記事の全てが終わります。皆さんの学習に役立つことを願っています。また、呐喊教程を多くのサポートをお願いします。
声明:この記事の内容はインターネットから取得され、著作権者に帰属します。コンテンツはインターネットユーザーによって自発的に貢献し、自己でアップロードされています。このサイトは所有権を持ちません。また、人工的な編集は行われていません。著作権侵害が疑われる場合は、メールを送信してください:notice#oldtoolbag.com(メールを送信する際、#を@に置き換えてください。告発を行い、関連する証拠を提供してください。一旦確認されると、このサイトは即座に侵害疑いのコンテンツを削除します。)