如何在滚动RecyclerView

时间:2016-01-11 06:55:51

标签: android android-toolbar android-appbarlayout

Google最近发布了设计支持库,引入了一些很酷的新视图。使用一些新组件(例如CoordinatorLayout)可能(!)使您能够实现滚动行为。

我尝试了一些内置的滚动行为,但没有任何对我有用,

我的布局中有一个底栏(LinearLayout)代替FloatingActionButton

这就是我想要的。

  1. 应该出现OnLaunch这个屏幕底栏。
  2. 在recyclelerview底部栏的滚动上应该滚动。
  3. 在recyclerview底栏的向下滚动应该滚动
  4. 是否有任何内置机制来实现这一目标?或者我们需要编写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>
    

7 个答案:

答案 0 :(得分:30)

我是这样做的:

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();

}

答案 1 :(得分:11)

因为您使用的是CoordinatorLayout,所以您可以创建一个自定义Behaviour,可以达到您所要求的效果,如下所示: create一个extends 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"

答案 2 :(得分:3)

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 like ..

 <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 :(得分:1)

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'

答案 4 :(得分:0)

@ 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();

}

答案 5 :(得分:0)

您的片段中的动画可见性和隐藏:

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();
}

答案 6 :(得分:0)

@ k0sh&#39; s QuickReturnFloaterBehavior有效,但有时候不会听轻微的卷轴。

我的NestedScrollView内容为LinearLayout作为底栏&amp;没有回收者的观点。所以,我无法使用其他建议的答案。

具有相同情况的人可以使用此帖Bottom Navigation Behavior中的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());
    }
}