16

いくつかの線形レイアウトやテキストビューのようなコンテンツを含むネストされたスクロールビューを持っています。いくつかの理由で、フローティングアクションボタンライブラリも使用しています。だから私はそれのためにどんな行動も使うことができません。scrollview から scrollchangelistener を処理して、fab を動作のように動的に非表示および表示する方法がわかりません。

スクロール中にファブを非表示および表示する方法はありますか?

4

5 に答える 5

12

FabScrollBehavior クラスを作成する

public class FabScrollBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
    private int toolbarHeight;

    public FabScrollBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.toolbarHeight = AppUtil.getToolbarHeight(context);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
        return dependency instanceof AppBarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
        if (dependency instanceof AppBarLayout) {
            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
            int fabBottomMargin = lp.bottomMargin;
            int distanceToScroll = fab.getHeight() + fabBottomMargin;
            float ratio = (float)dependency.getY()/(float)toolbarHeight;
            fab.setTranslationY(-distanceToScroll * ratio);
        }
        return true;
    }
}

AppUtil.getToolbarHeight(context) は -

public static int getToolbarHeight(Context context) {
        final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
                new int[]{R.attr.actionBarSize});
        int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
        styledAttributes.recycle();

        return toolbarHeight;
    }

次に、レイアウトで FloatingActionButton layout_behavior に追加します。

   <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_task_accept"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_accepted"
        app:layout_behavior="pass.to.your.FabScrollBehavior.Class"
        app:theme="@style/Widget.AppTheme.Fab"/>

全体のレイアウトはこんな感じ

<?xml version="1.0" encoding="utf-8"?>
<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:animateLayoutChanges="true"
    android:orientation="vertical">

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

        <include
            layout="@layout/include_layout_toolbar_scroll"/>

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


    <include layout="@layout/include_layout_content_with_nestedscroll"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_task_accept"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_accepted"
        app:layout_behavior="pass.to.FabScrollBehavior.Class"
        app:theme="@style/Widget.AppTheme.Fab"/>


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

https://mzgreen.github.io/2015/02/15/How-to-hideshow-Toolbar-when-list-is-scroling(part1)/から実装

于 2016-02-16T08:38:34.783 に答える
3

アクティビティまたはフラグメントで変数型 int を定義して、ScrollView から前の Scroll を設定し、このメソッドを使用して ScrollView クラスでスクロールの変更をリッスンします

 scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {

    // previousScrollY this variable is define in your Activity or Fragment
            if (scrollView.getScrollY() > previousScrollY && floatingActionButton.getVisibility() == View.VISIBLE) {
                floatingActionButton.hide();
            } else if (scrollView.getScrollY() < previousScrollY && floatingActionButton.getVisibility() != View.VISIBLE) {
                floatingActionButton.show();
            }
            previousScrollY = scrollView.getScrollY();
        }
    });

Androidのすべてのバージョンで動作します

于 2018-03-26T13:14:08.917 に答える
2

そのような時間を費やした後、私はそれに対する解決策を見つけました。あらゆる状況で機能する可能性があります。これは適切な解決策ではないハックですが、それを適用してこのことを機能させることができます。

私たちが知っているsetOnScrollChangeListenerように、最小APIが23の場合にのみ機能するため、最小APIレベルが23未満の場合はどうなりますか.

そのため、スタックオーバーフローから解決策を見つけたgetViewTreeObserver().addOnScrollChangedListenerので、これはすべてのデバイスで互換性のある解決策になります。

以上の問題の最終的な解決策に移りましょう。

Handlerそのため、 withを使用しpostDelayedてこの問題を解決できます。

  1. コンテキストで変数を定義するprivate int previousScrollY = 0;

  2. 次にgetViewTreeObserver().addOnScrollChangedListener、このようにネストされたスクロール ビューを使用します。

NESTEDSCROLLVIEW.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { new Handler().postDelayed(new Runnable() { @Override public void run() { if (NESTEDSCROLLVIEW.getScrollY() == previousScrollY) { FABBUTTON.setVisibility(View.VISIBLE); } else { FABBUTTON.setVisibility(View.INVISIBLE); } } }, 10); previousScrollY = NESTEDSCROLLVIEW.getScrollY(); } });

  1. これで準備完了です....
于 2019-11-20T05:10:26.690 に答える