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

Androidのカスタムビューで支付宝の「一掃」効果を実現

この記事では、カスタムViewと属性アニメーションを使用して以下のような効果を実現する方法を紹介します

実現方法は非常にシンプルです:

  • 半透明の円を描画します
  • クリック時とクリックしない時の拡散と収縮の2つのアニメーション効果を実現します
  • スレッドを使用して上記の2つのステップを組み合わせます

まず半透明円の描画部分を見てみましょう

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(メールを送信する際、#を@に置き換えてください。告発を行い、関連する証拠を提供してください。一旦確認されると、このサイトは即座に侵害疑いのコンテンツを削除します。)

おすすめ