实现Google+滑动显示、隐藏toolbar
先来看下效果图
google+.gif本文使用到RecyclerView、CardView、butterknife、FloatingActionBar
这里使用到了为RecyclerView添加header
可以看这篇 BaseRecyclerAdapter处理了header和footer
butterknife的使用看这篇
1、添加依赖
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:recyclerview-v7:24.0.0'
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
compile 'com.android.support:cardview-v7:24.0.0'
compile 'com.android.support:design:24.0.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
}```
####2、定义style
设置为不使用actionbar
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
####3、布局
主布局
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Activity.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="right|bottom"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
app:rippleColor="#ffffff"
android:elevation="6dp"
app:pressedTranslationZ="12dp"/>
</FrameLayout>
recyclerview的item布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
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="wrap_content"
app:cardBackgroundColor="#ffffff"
app:cardCornerRadius="10dp"
app:cardElevation="5dp"
app:contentPadding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_card"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/tv_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp" />
</LinearLayout>
</android.support.v7.widget.CardView>```
4、recyclerview的adapter
public class RecyclerAdapter extends BaseRecyclerAdapter<DataBean> {
private Context context;
public RecyclerAdapter(Context context){
this.context=context;
}
@Override
public RecyclerView.ViewHolder onCreate(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_google_plus,parent,false));
}
@Override
public void onBind(RecyclerView.ViewHolder viewHolder, int realPosition, DataBean data) {
if (viewHolder instanceof MyViewHolder){
Glide.with(context).load(data.getImageUrl()).into(((MyViewHolder) viewHolder).imageView);
((MyViewHolder) viewHolder).textView.setText(data.getText_content());
}
}
class MyViewHolder extends RecyclerAdapter.Holder {
private ImageView imageView;
private TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
imageView= (ImageView) itemView.findViewById(R.id.iv_card);
textView= (TextView) itemView.findViewById(R.id.tv_card);
}
}
}```
到此为止,先看下效果,会发现recycler顶部被toolbar覆盖了,这就是为什么要添加header的原因
![device-2016-11-29-110046.png](http:https://img.haomeiwen.com/i1814117/0a7a6a6a4190bda9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
####5、header布局
这里将header的高设置成和toolbar高一样
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
</LinearLayout>```
6、最后实现隐藏显示
这里的实现思路也比较简单,为recyclerview添加OnScrollListener
recycler向上滚动时dy为正,向下滚动时dy为负数
当recycler向上滑动距离超过设置的默认值并且toolbar可见时,隐藏toolbar和fab
当recycler向下滑动距离超过设置的默认值并且toolbar不可见时,显示toolbar和fab
最后的显示隐藏用属性动画来完成
recycler.setOnScrollListener(new HideScrollListener());
class HideScrollListener extends RecyclerView.OnScrollListener{
private static final int HIDE_HEIGHT=40;
private int scrolledInstance=0;
private boolean toolbarVisible=true;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if ((toolbarVisible&&dy>0)||!toolbarVisible&&dy<0){
//recycler向上滚动时dy为正,向下滚动时dy为负数
scrolledInstance+=dy;
}
if (scrolledInstance>HIDE_HEIGHT&&toolbarVisible){//当recycler向上滑动距离超过设置的默认值并且toolbar可见时,隐藏toolbar和fab
onHide();
scrolledInstance=0;
toolbarVisible=false;
}else if (scrolledInstance<-HIDE_HEIGHT&&!toolbarVisible){//当recycler向下滑动距离超过设置的默认值并且toolbar不可见时,显示toolbar和fab
onShow();
scrolledInstance=0;
toolbarVisible=true;
}
}
}
private void onHide() {
ObjectAnimator.ofFloat(toolbar,"translationY",0,-toolbar.getHeight()).setDuration(200).start();
ObjectAnimator.ofFloat(fab,"translationY",0,fab.getHeight()+fab.getPaddingBottom()).setDuration(200).start();
}
private void onShow() {
ObjectAnimator.ofFloat(toolbar,"translationY",-toolbar.getHeight(),0).setDuration(200).start();
ObjectAnimator.ofFloat(fab,"translationY",fab.getHeight()+fab.getPaddingBottom(),0).setDuration(200).start();
}
}```
####7、完整代码
public class MainActivity extends AppCompatActivity {
@BindView(R.id.recycler)
RecyclerView recycler;
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.fab)
FloatingActionButton fab;
private RecyclerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.google_scroll);
ButterKnife.bind(this);
//toolbar
setSupportActionBar(toolbar);
setTitle("Google+");
toolbar.setTitleTextColor(Color.parseColor("#ffffff"));
//recycler
recycler.setLayoutManager(new LinearLayoutManager(this));
adapter=new RecyclerAdapter(this);
adapter.addDatas(getdatas());
adapter.setHeader(LayoutInflater.from(this).inflate(R.layout.header,recycler,false));
recycler.setAdapter(adapter);
recycler.addItemDecoration(new SimpleItemDecration(20));
recycler.setOnScrollListener(new HideScrollListener());
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
T.showShort(MainActivity.this,"fab");
}
});
}
private ArrayList<DataBean> getdatas() {
ArrayList<DataBean> datas=new ArrayList<>();
for (int i = 0; i < 10; i++) {
datas.add(new DataBean("http://pic41.nipic.com/20140531/1812578_155037556122_2.jpg","君生我未生\n我生君已老"));
}
return datas;
}
class HideScrollListener extends RecyclerView.OnScrollListener{
private static final int HIDE_HEIGHT=20;
private int scrolledInstance=0;
private boolean toolbarVisible=true;
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if ((toolbarVisible&&dy>0)||!toolbarVisible&&dy<0){
//recycler向上滚动时dy为正,向下滚动时dy为负数
scrolledInstance+=dy;
}
if (scrolledInstance>HIDE_HEIGHT&&toolbarVisible){//当recycler向上滑动距离超过设置的默认值并且toolbar可见时,隐藏toolbar和fab
onHide();
scrolledInstance=0;
toolbarVisible=false;
}else if (scrolledInstance<-HIDE_HEIGHT&&!toolbarVisible){//当recycler向下滑动距离超过设置的默认值并且toolbar不可见时,显示toolbar和fab
onShow();
scrolledInstance=0;
toolbarVisible=true;
}
}
}
private void onHide() {
ObjectAnimator.ofFloat(toolbar,"translationY",0,-toolbar.getHeight()).setDuration(200).start();
ObjectAnimator.ofFloat(fab,"translationY",0,fab.getHeight()+fab.getPaddingBottom()).setDuration(200).start();
}
private void onShow() {
ObjectAnimator.ofFloat(toolbar,"translationY",-toolbar.getHeight(),0).setDuration(200).start();
ObjectAnimator.ofFloat(fab,"translationY",fab.getHeight()+fab.getPaddingBottom(),0).setDuration(200).start();
}
}```