RecyclerView 滑动隐藏,显示ToolBar

来源:互联网 发布:欧文职业生涯数据 编辑:程序博客网 时间:2024/05/09 03:41

一:去除自带的ActionBar,在styles.xml

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

二:布局文件,注意这里使用FrameLayout,是为了把ToolBar叠加放在RecyclerView上,如果不这样,当你隐藏ToolBar时,原ToolBar所在位置会出现空白。

<?xml version="1.0" encoding="utf-8"?><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/rv"        android:layout_width="match_parent"        android:layout_height="wrap_content"/>    <android.support.v7.widget.Toolbar        android:id="@+id/toolbar"        android:layout_width="match_parent"        android:layout_height="?actionBarSize"        android:background="?attr/colorPrimary"/></FrameLayout>

三:具体实现

package com.example.kirito.testapp.testtoolbarscroll;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.os.Bundle;import android.support.annotation.Nullable;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.LinearInterpolator;import com.example.kirito.testapp.R;import java.util.ArrayList;import java.util.List;/** * Created by kirito on 2017.02.13. */public class TooBarScroll extends AppCompatActivity {    private Toolbar toolbar;    private RecyclerView rv;    private RvAdapter adapter;    private List<String> list;    private static int THRESHOLD_OFFSET = 10;    private static final String TAG = "TooBarScroll";    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.toobar_scroll);        toolbar = (Toolbar) findViewById(R.id.toolbar);        setSupportActionBar(toolbar);        getSupportActionBar().setTitle(R.string.app_name);        rv = (RecyclerView) findViewById(R.id.rv);        rv.setLayoutManager(new LinearLayoutManager(this));        list = new ArrayList<>();        for (int i = 0; i < 100; i++) {            list.add(i + "");        }        adapter = new RvAdapter(this);        rv.setAdapter(adapter);        adapter.addAll(list);        rv.addOnScrollListener(new RecyclerView.OnScrollListener() {            boolean controlVisible = true;            int scrollDistance = 0;            //onScrolled 滑动停止的时候调用            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                if (controlVisible && scrollDistance > THRESHOLD_OFFSET){//手指上滑即Scroll向下滚动的时候,dy为正                    animationHide();                    //重置使下面的if语句起作用                    controlVisible = false;                    scrollDistance = 0;                }else if (!controlVisible && scrollDistance < -THRESHOLD_OFFSET){//手指下滑即Scroll向上滚动的时候,dy为负                    animationShow();                    controlVisible = true;                    scrollDistance = 0;                }                //当scrollDistance累计到隐藏(显示)ToolBar之后,如果Scroll向下(向上)滚动,则停止对scrollDistance的累加                //直到Scroll开始往反方向滚动,再次启动scrollDistance的累加                if ((controlVisible && dy > 0) || (!controlVisible && dy < 0)){                    scrollDistance += dy;                }            }        });    }    private void animationShow() {        toolbar.animate()                .setInterpolator(new AccelerateInterpolator(1))                .setDuration(180)                .translationY(0);    }    private void animationHide(){        toolbar.animate()                .translationY(-toolbar.getBottom())                .setInterpolator(new LinearInterpolator())                .setDuration(180);    }}

效果图:
这里写图片描述


这里有个问题,ToolBar把RecyclerView最开头的几行挡住了,因为布局文件里使用的是FrameLayout。

四:此时有两个解决方法,一是对RecyclerView的属性进行修改

<android.support.v7.widget.RecyclerView        android:id="@+id/rv"        android:paddingTop="?actionBarSize"        android:clipToPadding="false"//若没有这句在隐藏ToolBar的时候会出现空白,如下所示        android:layout_width="match_parent"        android:layout_height="wrap_content"/>

这里写图片描述

改进后的效果

这里写图片描述


五:第二种解决方法:在原ToolBar下面给RecyclerView添加一个子View

1.修改的RecyclerView adapter

package com.example.kirito.testapp.testtoolbarscroll;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.ViewGroup;import com.example.kirito.testapp.R;import java.util.ArrayList;import java.util.List;/** * Created by kirito on 2017.02.13. */public class RvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    private LayoutInflater mLayoutInflater;    private List<String> list = new ArrayList<>();    private int hearder = 0;    private int item = 1;    public RvAdapter(Context mContext) {        mLayoutInflater = LayoutInflater.from(mContext);    }    public void addAll(List<String> items){        list = items;    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //添加header        if (viewType == 0){            return new Holder(mLayoutInflater.inflate(R.layout.rv_header,parent,false));        }else {            return new Holder(mLayoutInflater.inflate(R.layout.rv_item,parent,false),0);        }    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        //不是header才绑定数据        if (position != 0){            ((Holder)holder).bindHolder(list.get(position - 1));        }    }    @Override    public int getItemViewType(int position) {        if (position == 0){            return hearder;        }else {            return item;        }    }    @Override    public int getItemCount() {        //count + 1        return list.size() + 1;    }}

2.修改的RecyclerView.ViewHolder

package com.example.kirito.testapp.testtoolbarscroll;import android.support.v7.widget.RecyclerView;import android.view.View;import android.widget.TextView;import com.example.kirito.testapp.R;/** * Created by kirito on 2017.02.13. */public class Holder extends RecyclerView.ViewHolder {    private TextView tv;    //使用不同的构造器区分    public Holder(View itemView) {        super(itemView);    }    public Holder(View itemView, int flag) {        super(itemView);        tv = (TextView) itemView.findViewById(R.id.rv_item_tv);    }    public void bindHolder(String i){        tv.setText(i);    }}

3.header的布局文件

<?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="?actionBarSize"/>

4.实现效果
这里写图片描述


六:这里还是有一个问题在ToolBar隐藏之后,显示header时会有空白

这时,只需修改onScrolled方法就可以了

@Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                int firstViewPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findFirstVisibleItemPosition();                if (firstViewPosition == 0){//当header是FirstVisibleItem并且隐藏了ToolBar时,显示ToolBar                    if (!controlVisible){                        animationShow();                        controlVisible = true;                    }                }else {                    if (controlVisible && scrollDistance > THRESHOLD_OFFSET){//手指上滑即Scroll向下滚动的时候,dy为正                        animationHide();                        //重置使下面的if语句起作用                        controlVisible = false;                        scrollDistance = 0;                    }else if (!controlVisible && scrollDistance < -THRESHOLD_OFFSET){//手指下滑即Scroll向上滚动的时候,dy为负                        animationShow();                        controlVisible = true;                        scrollDistance = 0;                    }                    //当scrollDistance累计到隐藏(显示)ToolBar之后,如果Scroll向下(向上)滚动,则停止对scrollDistance的累加                    //直到Scroll开始往反方向滚动,再次启动scrollDistance的累加                    if ((controlVisible && dy > 0) || (!controlVisible && dy < 0)){                        scrollDistance += dy;                    }                }            }        });

最后的效果图:
这里写图片描述

参考

0 0
原创粉丝点击