web-dev-qa-db-ja.com

RecyclerViewのスクロール時にボトムバーの上下にスクロールする方法

GoogleのDesign Support Libraryの最近のリリースで、いくつかのクールな新しいビューが導入されました。新しいコンポーネントの一部(CoordinatorLayoutなど)を使用すると、スクロール動作を実現できる可能性があります(!).

組み込みのスクロール動作を試してみましたが、何も機能しません。

レイアウトにFloatingActionButtonの代わりにボトムバー(LinearLayout)があります

ここで私が欲しいもの。

  1. この画面のOnLaunch下部バーが表示されます。
  2. Recyclerviewをスクロールアップすると、下部バーがスクロールダウンするはずです。
  3. Recyclerviewのスクロールダウン時に下部バーがスクロールアップするはずです

これを達成するための組み込みメカニズムはありますか?またはJavaコードを書く必要がありますか?

これが私のコードです:

main_activty.xml

<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:fitsSystemWindows="true">

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

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

        <Android.support.design.widget.TabLayout
            Android:id="@+id/tabs"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:elevation="5dp"
            app:tabGravity="fill"
            app:tabIndicatorColor="@Android:color/white"
            app:tabMode="fixed" />

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

    <!-- All Scrollable Views -->

    <Android.support.v4.view.ViewPager
        Android:id="@+id/viewpager"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <!-- Bottom bar-->

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_gravity="bottom"
        Android:background="#a0000000"
        Android:orientation="horizontal"
        Android:paddingBottom="@dimen/padding_small"
        Android:paddingTop="@dimen/padding_small">

        <TextView
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.33"
            Android:gravity="center"
            Android:paddingBottom="@dimen/padding_small"
            Android:paddingTop="@dimen/padding_small"
            Android:text="AC"
            Android:textColor="@color/white" />

        <TextView
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.33"
            Android:gravity="center"
            Android:paddingBottom="@dimen/padding_small"
            Android:paddingTop="@dimen/padding_small"
            Android:text="Sleeper"
            Android:textColor="@color/white" />

        <TextView
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.33"
            Android:gravity="center"
            Android:paddingBottom="@dimen/padding_small"
            Android:paddingTop="@dimen/padding_small"
            Android:text="Premium"
            Android:textColor="@color/white" />

    </LinearLayout>


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

fragment.xml(ここでは、recyclerviewコードを入力しました)

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@color/white"
    Android:orientation="vertical">

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="horizontal"
        Android:paddingBottom="@dimen/padding_small"
        Android:paddingTop="@dimen/padding_small"
        Android:weightSum="1">

        <TextView
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.33"
            Android:background="@drawable/bg_srp_sorter"
            Android:clickable="true"
            Android:gravity="center"
            Android:paddingBottom="@dimen/padding_small"
            Android:paddingTop="@dimen/padding_small"
            Android:text="Departure" />

        <TextView
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.33"
            Android:background="@drawable/bg_srp_sorter"
            Android:gravity="center"
            Android:paddingBottom="@dimen/padding_small"
            Android:paddingTop="@dimen/padding_small"
            Android:text="Duration" />

        <TextView
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.33"
            Android:gravity="center"
            Android:paddingBottom="@dimen/padding_small"
            Android:paddingTop="@dimen/padding_small"
            Android:text="Price" />

    </LinearLayout>

    <View
        Android:layout_width="match_parent"
        Android:layout_height="1dp"
        Android:background="@color/lite_gray"></View>

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:weightSum="1">

        <Android.support.v7.widget.RecyclerView
            Android:id="@+id/bus_list_recycler_view"
            Android:layout_width="match_parent"
            Android:layout_height="0dp"
            Android:layout_weight="1" />

    </LinearLayout>
</LinearLayout>

toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.Toolbar 

xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/toolbar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@color/colorPrimary"
    app:layout_scrollFlags="scroll|enterAlways"
    Android:minHeight="?attr/actionBarSize">


    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:weightSum="1">

        <LinearLayout
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.10">

            <ImageView
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:src="@drawable/abc_ic_ab_back_mtrl_am_alpha" />


        </LinearLayout>


        <LinearLayout
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.78"
            Android:orientation="vertical">

            <LinearLayout
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:orientation="horizontal"
                Android:weightSum="1">

                <TextView
                    Android:id="@+id/toolbar_title_source"
                    Android:layout_width="0dp"
                    Android:layout_height="wrap_content"
                    Android:layout_weight="0.47"
                    Android:ellipsize="end"
                    Android:singleLine="true"
                    Android:text="Thiruvananthapuram "
                    Android:textColor="@color/white"
                    Android:textSize="@dimen/label_text_size_large" />

                <TextView
                    Android:id="@+id/toolbar_title_arrow"
                    Android:layout_width="0dp"
                    Android:layout_height="wrap_content"
                    Android:layout_weight="0.08"
                    Android:text="@string/char_right"
                    Android:textColor="@color/white"
                    Android:textSize="@dimen/label_text_size_large"
                    Android:textStyle="bold" />

                <TextView
                    Android:id="@+id/toolbar_title_destination"
                    Android:layout_width="0dp"
                    Android:layout_height="wrap_content"
                    Android:layout_weight="0.47"
                    Android:ellipsize="end"
                    Android:singleLine="true"
                    Android:text=" Cochin"
                    Android:textColor="@color/white"
                    Android:textSize="@dimen/label_text_size_large" />


            </LinearLayout>


            <TextView
                Android:id="@+id/toolbar_sub_title"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="2 Seat(s)"
                Android:textColor="@color/lite_gray"
                Android:textSize="@dimen/label_text_size_normal" />

        </LinearLayout>


        <LinearLayout
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="0.13">

            <ImageView
                Android:layout_width="30dp"
                Android:layout_height="30dp"
                Android:scaleType="fitCenter"
                Android:src="@drawable/filter" />
        </LinearLayout>
    </LinearLayout>

</Android.support.v7.widget.Toolbar>
15

CoordinatorLayoutを使用しているので、以下の例に従って、要求したものを実現できるカスタムBehaviourを作成できます。createextends CoordinatorLayout.Behavior<View>以下の例に従ってください:

public class QuickReturnFloaterBehavior extends CoordinatorLayout.Behavior<View> {

    private int distance;

    public QuickReturnFloaterBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
    }

    @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed) {
        if (dy > 0 && distance < 0 || dy < 0 && distance > 0) {
            child.animate().cancel();
            distance = 0;
        }
        distance += dy;
        final int height = child.getHeight() > 0 ? (child.getHeight()) : 600/*update this accordingly*/;
        if (distance > height && child.isShown()) {
            hide(child);
        } else if (distance < 0 && !child.isShown()) {
            show(child);
        }
    }

    private void hide(View view) {
        view.setVisibility(View.GONE);// use animate.translateY(height); instead
    }

    private void show(View view) {
        view.setVisibility(View.VISIBLE);// use animate.translateY(-height); instead
    }

}

これを適用するにはbehaviourこれをレイアウトに追加します

app:layout_behavior="com.example.QuickReturnFloaterBehavior"
11
k0sh

これは私がやった方法です:

mRecylerView.addOnScrollListener(new HideShowScrollListener() {
            @Override
            public void onHide() {
                //fab.animate().setInterpolator(new AccelerateDecelerateInterpolator()).scaleX(0).scaleY(0);
               // do your hiding animation here

            }

            @Override
            public void onShow() {
               // fab.animate().setInterpolator(new AccelerateDecelerateInterpolator()).scaleX(1).scaleY(1);
              // do your showing animation here
            }
        });

HideShowScrollListener.classが必要になります

/**
* This class is a ScrollListener for RecyclerView that allows to show/hide
* views when list is scrolled.
* */
public abstract class HideShowScrollListener extends RecyclerView.OnScrollListener {
    private static final int HIDE_THRESHOLD = 20;
    private int scrolledDistance = 0;
    private boolean controlsVisible = true;

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        if (scrolledDistance > HIDE_THRESHOLD && controlsVisible) {
            onHide();
            controlsVisible = false;
            scrolledDistance = 0;
        } else if (scrolledDistance < -HIDE_THRESHOLD && !controlsVisible) {
            onShow();
            controlsVisible = true;
            scrolledDistance = 0;
        }

        if((controlsVisible && dy>0) || (!controlsVisible && dy<0)) {
            scrolledDistance += dy;
        }
    }

    public abstract void onHide();
    public abstract void onShow();

}
30
krishan
public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
    private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
    private boolean mIsAnimatingOut = false;
public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
    super();
}

@Override
public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                                   final View directTargetChild, final View target, final int nestedScrollAxes) {
    // Ensure we react to vertical scrolling
    return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
            || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
}

@Override
public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                           final View target, final int dxConsumed, final int dyConsumed,
                           final int dxUnconsumed, final int dyUnconsumed) {
    super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
    if (dyConsumed > 0 && !this.mIsAnimatingOut && child.getVisibility() == View.VISIBLE) {
        // User scrolled down and the FAB is currently visible -> hide the FAB
        animateOut(child);
    } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
        // User scrolled up and the FAB is currently not visible -> show the FAB
        animateIn(child);
    }
}

// Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits
private void animateOut(final FloatingActionButton button) {
    if (Build.VERSION.SDK_INT >= 14) {
        ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer()
                .setListener(new ViewPropertyAnimatorListener() {
                    public void onAnimationStart(View view) {
                        ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
                    }

                    public void onAnimationCancel(View view) {
                        ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
                    }

                    public void onAnimationEnd(View view) {
                        ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
                        view.setVisibility(View.GONE);
                    }
                }).start();
    } else {
        Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out);
        anim.setInterpolator(INTERPOLATOR);
        anim.setDuration(200L);
        anim.setAnimationListener(new Animation.AnimationListener() {
            public void onAnimationStart(Animation animation) {
                ScrollAwareFABBehavior.this.mIsAnimatingOut = true;
            }

            public void onAnimationEnd(Animation animation) {
                ScrollAwareFABBehavior.this.mIsAnimatingOut = false;
                button.setVisibility(View.GONE);
            }

            @Override
            public void onAnimationRepeat(final Animation animation) {
            }
        });
        button.startAnimation(anim);
    }
}

// Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters
private void animateIn(FloatingActionButton button) {
    button.setVisibility(View.VISIBLE);
    if (Build.VERSION.SDK_INT >= 14) {
        ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F)
                .setInterpolator(INTERPOLATOR).withLayer().setListener(null)
                .start();
    } else {
        Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in);
        anim.setDuration(200L);
        anim.setInterpolator(INTERPOLATOR);
        button.startAnimation(anim);
    }
}

}

xml app:layout_behaviorのように設定します。

 <Android.support.design.widget.FloatingActionButton
    Android:id="@+id/fab"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_gravity="end|bottom"
    Android:layout_margin="16dp"
    app:fabSize="mini"
    Android:src="@drawable/ic_action_edit"
    app:layout_behavior="com.package.name.ScrollAwareFABBehavior"/>
3
Sambhaji Karad

enter image description here

package com.keshav.hideactionbarandfooterexample;

import Android.os.Bundle;
import Android.support.v7.app.AppCompatActivity;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.support.v7.widget.Toolbar;
import Android.util.Log;
import Android.view.View;
import Android.view.animation.AccelerateInterpolator;
import Android.view.animation.DecelerateInterpolator;
import Android.widget.FrameLayout;
import Android.widget.ImageButton;

import Java.util.ArrayList;
import Java.util.List;

import adapters.RecyclerAdapter;
import listners.HidingScrollListener;

public class MainActivity extends AppCompatActivity {

    private Toolbar mToolbar;
    private Toolbar toolbar_bottom;
    private ImageButton mFabButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.AppThemeRed);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.e("keshav", "MainActivity called");

        initToolbar();
        mFabButton = (ImageButton) findViewById(R.id.fabButton);
        initRecyclerView();
    }

    private void initToolbar() {
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar_bottom = (Toolbar) findViewById(R.id.toolbar_bottom);
        setSupportActionBar(mToolbar);
        setSupportActionBar(toolbar_bottom);
        setTitle(getString(R.string.app_name));
        mToolbar.setTitleTextColor(getResources().getColor(Android.R.color.white));
        toolbar_bottom.setTitleTextColor(getResources().getColor(Android.R.color.white));


        toolbar_bottom.setVisibility(View.GONE);
    }

    private void initRecyclerView() {
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        RecyclerAdapter recyclerAdapter = new RecyclerAdapter(createItemList());
        recyclerView.setAdapter(recyclerAdapter);

        recyclerView.addOnScrollListener(new HidingScrollListener() {
            @Override
            public void onHide() {
                hideViews();
            }

            @Override
            public void onShow() {
                showViews();
            }
        });
    }

    private void hideViews() {
        // TODO (-mToolbar)  plus means  2 view above ho jaye or not visible to user
        mToolbar.animate().translationY(-mToolbar.getHeight()).setInterpolator(new AccelerateInterpolator(2));

        // TODO uncomment this Hide Footer in Android when Scrolling
        // TODO (+mToolbar)  plus means  2 view forward ho jaye or not visible to user
        toolbar_bottom.animate().translationY(+toolbar_bottom.getHeight()).setInterpolator(new AccelerateInterpolator(2));

        // TODO keshav Hide Also Floatng Button In Android
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mFabButton.getLayoutParams();
        int fabBottomMargin = lp.bottomMargin;
        mFabButton.animate().translationY(mFabButton.getHeight() + fabBottomMargin).setInterpolator(new AccelerateInterpolator(2)).start();
        // TODO keshav Hide Also Floatng Button In Android
    }

    private void showViews() {
        mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));

        // TODO uncomment this Hide Footer in Android when Scrolling
        toolbar_bottom.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
        mFabButton.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();
    }

    private List<String> createItemList() {
        List<String> itemList = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            itemList.add("Item " + i);
        }
        return itemList;
    }
}

=============================================
             RecyclerAdapter
=============================================
package adapters;

import Android.content.Context;
import Android.support.v7.widget.RecyclerView;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;

import com.keshav.hideactionbarandfooterexample.R;

import Java.util.List;

/*
* RecyclerView Adapter that allows to add a header view.
* */
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int TYPE_HEADER = 2;
    private static final int TYPE_ITEM = 1;
    private List<String> mItemList;

    public RecyclerAdapter(List<String> itemList) {
        mItemList = itemList;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        if (viewType == TYPE_ITEM) {
            final View view = LayoutInflater.from(context).inflate(R.layout.recycler_item, parent, false);
            return RecyclerItemViewHolder.newInstance(view);
        } else if (viewType == TYPE_HEADER) {
            final View view = LayoutInflater.from(context).inflate(R.layout.recycler_header, parent, false);
            return new RecyclerHeaderViewHolder(view);
        }
        throw new RuntimeException("There is no type that matches the type " + viewType + " + make sure your using types correctly");
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        if (!isPositionHeader(position)) {
            RecyclerItemViewHolder holder = (RecyclerItemViewHolder) viewHolder;
            String itemText = mItemList.get(position - 1); // header
            holder.setItemText(itemText);
        }
    }

    public int getBasicItemCount() {
        return mItemList == null ? 0 : mItemList.size();
    }


    @Override
    public int getItemViewType(int position) {
        if (isPositionHeader(position)) {
            return TYPE_HEADER;
        }

        return TYPE_ITEM;
    }

    @Override
    public int getItemCount() {
        return getBasicItemCount() + 1; // header
    }

    private boolean isPositionHeader(int position) {
        return position == 0;
    }

}

=====================================================
         RecyclerHeaderViewHolder
=====================================================
package adapters;

import Android.support.v7.widget.RecyclerView;
import Android.view.View;

public class RecyclerHeaderViewHolder extends RecyclerView.ViewHolder {
    public RecyclerHeaderViewHolder(View itemView) {
        super(itemView);
    }
}

=====================================================
              RecyclerItemViewHolder
=====================================================

package adapters;

import Android.support.v7.widget.RecyclerView;
import Android.view.View;
import Android.widget.TextView;

import com.keshav.hideactionbarandfooterexample.R;


public class RecyclerItemViewHolder extends RecyclerView.ViewHolder {

    private final TextView mItemTextView;

    public RecyclerItemViewHolder(final View parent, TextView itemTextView) {
        super(parent);
        mItemTextView = itemTextView;
    }

    public static RecyclerItemViewHolder newInstance(View parent) {
        TextView itemTextView = (TextView) parent.findViewById(R.id.itemTextView);
        return new RecyclerItemViewHolder(parent, itemTextView);
    }

    public void setItemText(CharSequence text) {
        mItemTextView.setText(text);
    }

}

===================================================
            activity_main.xml
===================================================

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent">

    <Android.support.v7.widget.RecyclerView
            Android:id="@+id/recyclerView"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"/>

    <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="?attr/colorPrimary"/>

    <ImageButton
            Android:id="@+id/fabButton"
            Android:layout_width="56dp"
            Android:layout_height="56dp"
            Android:layout_gravity="bottom|right"
            Android:layout_marginBottom="16dp"
            Android:layout_marginRight="16dp"
            Android:background="@drawable/fab_bcg"
            Android:src="@drawable/ic_favorite_outline_white_24dp"
            Android:contentDescription="@string/fab_description"/>


    <RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

    <Android.support.v7.widget.Toolbar
        Android:id="@+id/toolbar_bottom"
        Android:layout_width="match_parent"
        Android:layout_alignParentBottom="true"
        Android:layout_height="?attr/actionBarSize"
        Android:background="?attr/colorPrimary"/>

    </RelativeLayout>

</FrameLayout>


==================================================
    recycle_header.xml in layout folder
==================================================

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:Android="http://schemas.Android.com/apk/res/Android"
      Android:layout_width="match_parent"
      Android:layout_height="?attr/actionBarSize"/>

==================================================
    recycle_item.xml in layout folder
==================================================
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.widget.CardView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:card_view="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_gravity="center"
    Android:layout_margin="8dp"
    card_view:cardCornerRadius="4dp">
    <TextView
        Android:id="@+id/itemTextView"
        Android:layout_width="match_parent"
        Android:layout_height="?attr/listPreferredItemHeight"
        Android:gravity="center_vertical"
        Android:padding="8dp"
        style="@style/Base.TextAppearance.AppCompat.Body2"/>
</Android.support.v7.widget.CardView>


=================================================
                      styles.xml
=================================================
<resources>

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    </style>

    <style name="AppThemeRed" parent="AppTheme">
        <item name="colorPrimary">@color/color_primary_red</item>
        <item name="colorPrimaryDark">@color/color_primary_red_dark</item>
    </style>

    <style name="AppThemeGreen" parent="AppTheme">
        <item name="colorPrimary">@color/color_primary_green</item>
        <item name="colorPrimaryDark">@color/color_primary_green_dark</item>
    </style>

    <style name="AppThemeBlue" parent="AppTheme">
        <item name="colorPrimary">@color/color_primary_blue</item>
        <item name="colorPrimaryDark">@color/color_primary_blue_dark</item>
        <item name="colorAccent">@color/color_accent_pink</item>
    </style>

</resources>

build.gradle依存関係

  compile 'com.Android.support:appcompat-v7:25.3.1'
    compile 'com.Android.support:recyclerview-v7:25.3.1'
    compile 'com.Android.support:cardview-v7:25.3.1'
    compile 'com.Android.support:design:25.3.1'
1
Keshav Gera

@ k0shの QuickReturnFloaterBehavior は機能しますが、わずかなスクロールが聞こえないことがあります。

NestedScrollViewにコンテンツがあり、下部バーとしてLinearLayoutがあり、リサイクラービューがありませんでした。そのため、他の推奨される回答は使用できません。

同じ状況の人は、この投稿のBottomNavigationBehaviorボトムナビゲーションの動作 を使用できます。それは完全に機能し、便利です。

現在のトップレベルビューにコンテンツがスクロールしている場合、下部のナビゲーションは、下にスクロールすると非表示になり、コンテンツを上にスクロールすると元に戻ります。このためには、スクロールの方向に注意する必要があります。 VerticalScrollingBehavior は、スクロール方向のイベントをディスパッチするCoordinatorLayout.Behaviorの拡張である、一般的なレイアウト動作です。

bottomNavigationBehaviorのソースコード- https://Gist.github.com/NikolaDespotoski/1d6fef4949eb9be05a46#file-bottomnavigationbehavior-Java

BottomNavigationBehaviorからのスニペット

@Override
public void onDirectionNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed, @ScrollDirection int scrollDirection) {
    handleDirection(child, scrollDirection);
}

@Override
protected boolean onNestedDirectionFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, @ScrollDirection int scrollDirection) {
    handleDirection(child, scrollDirection);
    return true;
}

private void handleDirection(V child, @ScrollDirection int scrollDirection) {
    if (!scrollingEnabled) return;
    if (scrollDirection == ScrollDirection.SCROLL_DIRECTION_DOWN && hidden) {
        hidden = false;
        animateOffset(child, 0);
    } else if (scrollDirection == ScrollDirection.SCROLL_DIRECTION_UP && !hidden) {
        hidden = true;
        animateOffset(child, child.getHeight());
    }
}
0
Vignesh Sundar

フラグメントの可視性とアニメーションによる非表示:

recyclerView.addOnScrollListener(new HideShowScrollListener() {
        final Fragment parentFragment = getParentFragment();
        @Override
        public void onHide() {
            bottomLayout.animate().setDuration(200).translationYBy(-bottomLayout.getHeight()).setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        bottomLayout.setVisibility(View.GONE);
                    }
            });
        }

        @Override
        public void onShow() {
            bottomLayout.animate().setDuration(200).translationY(0).setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        bottomLayout.setVisibility(View.VISIBLE);
                    }
            });
        }

        @Override
        public void onScrolled() {
            // To load more data
        }
    });

HideShowScrollListener.Java

public abstract class HideShowScrollListener extends RecyclerView.OnScrollListener {
        private static final int HIDE_THRESHOLD = 20;
        private int scrolledDistance = 0;
        private boolean controlsVisible = true;

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            onScrolled();

            if (scrolledDistance > HIDE_THRESHOLD && controlsVisible) {
                onHide();
                controlsVisible = false;
                scrolledDistance = 0;
            } else if (scrolledDistance < -HIDE_THRESHOLD && !controlsVisible) {
                onShow();
                controlsVisible = true;
                scrolledDistance = 0;
            }

            if((controlsVisible && dy>0) || (!controlsVisible && dy<0)) {
                scrolledDistance += dy;
            }
        }

        public abstract void onHide();
        public abstract void onShow();
        public abstract void onScrolled();
}
0
Naveen Kumar M

@ k0shは良い解決策を与えました。レイアウトを表示したり非表示にしたりして、アニメーションをスムーズにするために更新したいと思います。 onNestedPreScroll()内の完全なコードを以下のコードで置き換えます。

if (dy > 0) {

        CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
        int viewBottomMargin = layoutParams.bottomMargin;
        child.animate().translationY(child.getHeight() + viewBottomMargin).setInterpolator(new LinearInterpolator()).start();

} else if (dy < 0) {

        child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();

}
0
Prashant