web-dev-qa-db-ja.com

RecyclerViewアイテムのスクロールが遅いと、アンカー付きのフローティングアクションボタンが非表示にならない

デザインは下部にあります。

タブレイアウトの上で発生させたいこと:

  1. ユーザーがいずれかのタブでRecyclerViewを下にスクロールすると非表示になるAppBarLayoutが必要です。
  2. ユーザーの画像を背後の青い背景に添付し、ユーザーが下にスクロールしたときに非表示にしたい。
  3. ユーザーがスクロールしたときにタブを上部に固定して、簡単に切り替えられるようにしたい。ユーザーが下にスクロールしたときに見えるのは、リサイクル表示とタブレイアウトだけです。

だから私は1と3を達成しましたが、2を達成することはできません-RecyclerViewをゆっくりスクロールすると、画像はその上にとどまり、非表示になりません。

これが私がしたことです:

  1. ここに表示されているフラグメントにのみコーディネーターレイアウトを実装しました。新しいアクティビティ、またはフラグメントをホストするアクティビティには実装されておらず、フラグメントにはツールバーがありません。つまり、ツールバーのないCollapsingToolbarLayoutを使用しています。
  2. サポートデザインライブラリのフローティングアクションボタンを使用してユーザー画像を表示しています。隠すときはアニメーションでやるので使っています。

下部のXMLを確認してください。

だから何が起こります:

  1. すべてが完璧に読み込まれます
  2. ボタンが正しい位置に取り付けられている
  3. AppBarLayoutはスクロールに応答します
  4. ゆっくりスクロールするとボタンが隠れない
  5. 速くスクロールすると非表示になります
  6. ビューページャーのフラグメントを変更すると、非表示になります

これが問題のあるビデオです: [〜#〜] youtube [〜#〜]

CoordinatorLayoutをデバッグしようとしたところ、ボタンのhide()メソッドが呼び出されましたが、問題を見つけることができませんでした。何か案は?

編集1:

Cheesesquareの例でツールバーを削除すると、同じバグが発生します。

私のテストxml:

<?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:clickable="true"
    Android:background="@color/bg_secondary"
    Android:fitsSystemWindows="true"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/app_bar_layout"
        Android:elevation="1dp"
        Android:fitsSystemWindows="true"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <Android.support.design.widget.CollapsingToolbarLayout
            Android:id="@+id/collapsing_toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary"
            Android:fitsSystemWindows="true">

            <ImageView
                Android:id="@+id/img"
                Android:src="@drawable/header_bg"
                Android:scaleType="centerCrop"
                Android:cropToPadding="true"
                app:layout_collapseMode="parallax"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content" />

        </Android.support.design.widget.CollapsingToolbarLayout>
    </Android.support.design.widget.AppBarLayout>


    <Android.support.v4.view.ViewPager
        Android:id="@+id/profile_tabs"
        Android:elevation="2dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/test"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:elevation="1dp"
        app:pressedTranslationZ="12dp"
        Android:clickable="true"
        app:rippleColor="@Android:color/transparent"
        Android:src="@drawable/ic_launcher"
        app:layout_collapseMode="parallax"
        app:layout_anchor="@id/app_bar_layout"
        app:layout_anchorGravity="bottom|left|end" />

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

Sample design

編集2:

この問題には Declined とマークされた問題もあります。

13
NMP

必要な効果を得るには、FABのカスタム動作を実装する必要があります。ツールバーなしで機能するように、元の実装を少し変更しました。

    public class FABBehavior extends FloatingActionButton.Behavior {

    public FABBehavior() {
    }

    public FABBehavior(Context context, AttributeSet attributeSet) {
    }

    public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
        if(dependency instanceof Snackbar.SnackbarLayout) {
           return super.onDependentViewChanged(parent, child, dependency);
        } else if(dependency instanceof AppBarLayout) {
            this.updateFabVisibility(parent, (AppBarLayout)dependency, child);
        }

        return false;
    }

    private boolean updateFabVisibility(CoordinatorLayout parent, AppBarLayout appBarLayout, FloatingActionButton child) {
        CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams)child.getLayoutParams();
        if(lp.getAnchorId() != appBarLayout.getId()) {
            return false;
        } else {

            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) child.getLayoutParams();
            int point = child.getTop() - params.topMargin;
            try {
                Method method = AppBarLayout.class.getDeclaredMethod("getMinimumHeightForVisibleOverlappingContent");
                method.setAccessible(true);
                if(point <= (int) method.invoke(appBarLayout)) {
                    child.hide();
                } else {
                    child.show();
                }
                return true;
            } catch (Exception e) {
                return true;
            }
        }
    }
}

もちろん、app:layout_behaviorを使用してこの動作を適用できます。

7
dtx12

同様の問題があり、以下のように修正しました:

AppBarLayout appBarLayout = (AppBarLayout)findViewById(R.id.app_bar_layout);
    appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
            if(fab.getTop() <= 0) {
                fab.hide();
            } else {
                fab.show();
            }
        }
    });

このコードはアクティビティクラス内にあり、このコードはLollipopで実行しています。

2
Varini Ramesh