Material DesignシリーズのBehavior上滑り表示がトップボタンに戻ります。


効果のプレビュー

ソースは文章の最後にあります。
引用文
私達のページの内容が長すぎる時、ページの底にスライドしてユーザーが上にスライドするのは面倒くさいです。AndroidはiOSと違ってstatusBarをクリックしてトップに戻ることができます。普通はToolbar/アクションバーをダブルクリックするか、下にボタンを置くのです。
今日は下の方に上に戻るボタンを置いて、Behaviorに基づいて実現します。私たちの伝統的なやり方はこのスライドビューを監督することです。例えば、ScrelView/ListView/RecyclerView/GridViewなどを使ったら、すべてが非常にsoeasuryになります。
今日はユーザー定義のBehaviorを使って、トップボタンに戻る漸次的なアニメーション効果を実現します。私のBehaviorブログに興味があれば、他のBehaviorに関するブログを記事のトップに見つけられます。
カスタマイズBahaviorの実現?
私たちはCoordinaorLayout.Behaviorの後ctrl+tを選んだら、たくさんの実現類があります。どれを選びますか?ここでは私たちが操作するボタン(表示/非表示)を見ます。果たしてシステムで実現した基質を使ってもいいですか?だからまた次の問題を投げました。
Behaviorの後継システムはどのBaseBahaviorをカスタマイズしますか?
この問題はso easuryです。MDに接触した人はFABを聞いたことがありますよね。つまりFloat ActionButtonです。だから私達もFloat ingActionを使っています。だから私達がカスタマイズしたBehaviorもFloat Actionに基づいています。
そこで、私たちは中のCoordinatolayout.Behaviorの後ctrl+tの中からFloat at ingAction.Behaviorを見ました。このやつは私たちが受け継ぐものです。これを利用して、Float at ingActrl Butonの表示と隠しアニメーションを制御します。
ScaleUpShow Behaviorの実現
上に指をスライドさせるので、下の部分のページが出てきます。Buttonを表示します。それを一応ScaleUpShow Behaviorといいます。
次の大きな波のコードが襲来しました。まずFloat at atアクションButon.Behaviorを継承します。

public class ScaleUpShowBehavior extends FloatingActionButton.Behavior {
  public ScaleUpShowBehavior(Context context, AttributeSet attrs) {
    super();
  }
}

次にこの中の重要な3つの方法を実現します。

//       。
onStartNestedScroll();

//       。
onNestedScroll();

//       。
onStopNestedScroll();

最初の方法はonStartNestedScrrollである:
onStartNestedScroll(CoordinatorLayout l, FloatingActionButton c, View directTargetChild, View v, int nestedScrollAxes)
onStartNestedScrrol望文の意味は、スクロールを開始する時に呼び出されます。この方法にはブーメランの戻り値があります。CoordinatoLayoutに教えてほしいです。このBehaviorのスライド方向は、上下スライド時に表示/非表示FABなので、ここでreturn ness tedScrrollaxs=Viewl.AXIS_VERICAL。
第二の方法onNestedScrroll:
onNestedScroll(CoordinatorLayout l, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)
この方法はスライドの間に呼び出されました。つまりスライドしています。私たちはここでviewのアニメをコントロールします。私のテストでルールを見つけました。

if (dyConsumed > 0 && dyUnconsumed == 0) {
  System.out.println("   。。。");
}
if (dyConsumed == 0 && dyUnconsumed > 0) {
  System.out.println("        。。。");
}
if (dyConsumed < 0 && dyUnconsumed == 0) {
  System.out.println("   。。。");
}
if (dyConsumed == 0 && dyUnconsumed < 0) {
  System.out.println("    ,    。。。");
}

したがって、私たちがいる時に滑ります。つまり、ユーザーがページの下の部分を見たい時にFABを表示します。

if (((dyConsumed > 0 && dyUnconsumed == 0) || (dyConsumed == 0 && dyUnconsumed > 0))
&& child.getVisibility() != View.VISIBLE) {//   
      AnimatorUtil.scaleShow(child, null);
    }

反対に、ユーザの指がすべり、ページの上半分が表示されたときにFABを隠します。

if (((dyConsumed < 0 && dyUnconsumed == 0) || (dyConsumed == 0 && dyUnconsumed < 0))
&& child.getVisibility() != View.GONE && !isAnimatingOut) {
      AnimatorUtil.scaleHide(child, viewPropertyAnimatorListener);
    }

ここの完全なコードは以下の通りです。

@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {

//    if (dyConsumed > 0 && dyUnconsumed == 0) {
//      System.out.println("   。。。");
//    }
//    if (dyConsumed == 0 && dyUnconsumed > 0) {
//      System.out.println("        。。。");
//    }
//    if (dyConsumed < 0 && dyUnconsumed == 0) {
//      System.out.println("   。。。");
//    }
//    if (dyConsumed == 0 && dyUnconsumed < 0) {
//      System.out.println("    ,    。。。");
//    }

  if (((dyConsumed > 0 && dyUnconsumed == 0) || (dyConsumed == 0
  && dyUnconsumed > 0)) && child.getVisibility() != View.VISIBLE) {//   
    AnimatorUtil.scaleShow(child, null);
  } else if (((dyConsumed < 0 && dyUnconsumed == 0) || (dyConsumed == 0
  && dyUnconsumed < 0)) && child.getVisibility() != View.GONE && !isAnimatingOut) {
    AnimatorUtil.scaleHide(child, viewPropertyAnimatorListener);
  }
}

アニメーションのFAB表示と隠しの実現
目の鋭い人はきっと見ました。私たちの上から何票かの未知のコードが出てきます。

AnimatorUtil.scaleShow();
AnimatorUtil.scaleHide();
isAnimatingOut;
viewPropertyAnimatorListener;
これは何の幽霊ですか?
AnimatoUtil.scaleShow()は、システムではなく、カスタムアニメーションで使用されます。

//   view
public static void scaleShow(View view, ViewPropertyAnimatorListener viewPropertyAnimatorListener) {
  view.setVisibility(View.VISIBLE);
  ViewCompat.animate(view)
      .scaleX(1.0f)
      .scaleY(1.0f)
      .alpha(1.0f)
      .setDuration(800)
      .setListener(viewPropertyAnimatorListener)
      .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
      .start();
}

AnimatoUtil.scaleHideはFABをだんだん隠していくために使われています。もちろん私達のカスタムアニメーションです。

//   view
public static void scaleHide(View view, ViewPropertyAnimatorListener viewPropertyAnimatorListener) {
  ViewCompat.animate(view)
      .scaleX(0.0f)
      .scaleY(0.0f)
      .alpha(0.0f)
      .setDuration(800)
      .setInterpolator(FAST_OUT_SLOW_IN_INTERPOLATOR)
      .setListener(viewPropertyAnimatorListener)
      .start();
}

View PropertyAnimation Listenerとis Animating Outは、隠しアニメーションの実行を監督するために使用され、アニメーションが実行された後にview.set Visibility(View.gone)が実行されます。これがセットです。ハハ:

private boolean isAnimatingOut = false;

ViewPropertyAnimatorListener viewPropertyAnimatorListener = new ViewPropertyAnimatorListener() {

  @Override
  public void onAnimationStart(View view) {
    isAnimatingOut = true;
  }

  @Override
  public void onAnimationEnd(View view) {
    isAnimatingOut = false;
    view.setVisibility(View.GONE);
  }

  @Override
  public void onAnimationCancel(View arg0) {
    isAnimatingOut = false;
  }
};

ScaleUpShow Behaviorの使用
まずシステムを学びます。同じようにString.xmlに値を定義します。
 com.yanzhenjie.definebehavior.behavior.ScaleUpShowBehavior
xmlレイアウトで使用します。

<android.support.design.widget.FloatingActionButton
  android:id="@+id/fab"
  ...
  app:layout_behavior="@string/scale_up_show_behavior" />
もちろんあなたも完全にxmlレイアウトに直接にこの類の全類名を書いていますが、このような状況は今後この類の所在のカバンを修正するのに役立ちません。
ap:layout_behavior=「comp.yanzhenjie.definebehavior.behavior.ScaleUpShow Behavior」
はい、こまごまとしたものが終わったら、このレイアウトの完全なコードをかき集めてください。

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      android:layout_width="match_parent"
      android:layout_height="?attr/actionBarSize"
      app:popupTheme="@style/AppTheme.PopupOverlay" />
  </android.support.design.widget.AppBarLayout>

  <android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

  <android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="16dp"
    android:src="@mipmap/abc_ic_ab_back_top"
    app:layout_behavior="@string/scale_up_show_behavior"
    app:layout_scrollFlags="scroll|enterAlways|snap" />

</android.support.design.widget.CoordinatorLayout>

そしてRecyclerViewに適当にデータを渡して、走ってみてはは、完璧ですか?
そうだ、あるクラスメートはactivityが運行しているとこのFABを見ました。だから私達はワンウェイフォックスChanged()の中に隠れていなければなりません。

private boolean isInitializeFAB = false;

@Override
public void onWindowFocusChanged(boolean hasFocus) {
  super.onWindowFocusChanged(hasFocus);
  if (!isInitializeFAB) {
    isInitializeFAB = true;
    hideFAB();
  }
}

private void hideFAB() {
  FAB.postDelayed(new Runnable() {
    @Override
    public void run() {
      AnimatorUtil.scaleHide(FAB, new ViewPropertyAnimatorListener() {
        @Override
        public void onAnimationStart(View view) {
        }
        @Override
        public void onAnimationEnd(View view) {
          FAB.setVisibility(View.GONE);
        }
        @Override
        public void onAnimationCancel(View view) {
        }
      });
    }
  }, 500);
}

完璧ですね
ソースのダウンロード:http://xiazai.jb51.net/201609/yuanma/AndroidBehavior(jb 51.net)rar
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。