CoordinatorLayout配合AppBarLayout,Toolbar和TabLayout的使用,滑动隐藏标题头

关于Toolbar和TabLayout的使用,如果不了解的话,可以先看看这几篇文章: 

 TabLayout的使用,轻松实现带标题头的ViewPager

Toolbar的使用,替代了actionbar

使用RecyclerView实现ListView,GridView的效果(上下,左右滑动)

使用之前还需添加依赖:

compile 'com.android.support:design:24.2.0'

这里还得提醒一下,由于我们使用了ToolBar来替换系统默认的ActionBar,所以必须要隐藏标题头,方法有:

/**
 * 用android.support.v7.widget.Toolbar替换ActionBar,所以需要隐藏原有的标题头:
        方法1.设置App主题为:Theme.AppCompat.Light.NoActionBar
        方法2. supportRequestWindowFeature(Window.FEATURE_NO_TITLE)去掉了默认的导航栏(如果是继承了AppCompatActivity的,
               如果是继承Activity就应该调用 requestWindowFeature(Window.FEATURE_NO_TITLE) )
 */

也可以在 /res/values/style.xml中配置隐藏ActionBar和title.

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="AppTheme.Base"></style>

    <style name="AppTheme.Base"  parent="Theme.AppCompat">
        <!--隐藏ActionBar和标题-->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <!--ToolBar的颜色-->
        <item name="colorPrimary">@color/colorPrimary</item>
        <!--状态栏的颜色-->
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <!--EditText,RadioButton,CheckBox的点击效果颜色-->
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

代码如下:MainActivity

import android.graphics.Color;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
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.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

/**
 * 用android.support.v7.widget.Toolbar替换ActionBar,所以需要隐藏原有的标题头
 */
public class MainActivity extends AppCompatActivity {

    /**
     * 替换活动条的工具条
     */
    private Toolbar toolbar;

    /**
     * 选型卡布局
     */
    private TabLayout tabLayout;

    /**
     * 复用的控件,用来显示内容
     */
    private RecyclerView recyclerView;

    /**
     * 存放RecyclerView的数据
     */
    private ArrayList<String> data = new ArrayList<>();;
    private MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        tabLayout = (TabLayout)findViewById(R.id.tabLayout);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

        initToolbar();
        initTabLayout();
        initRecyclerView();
    }

    /**
     * 初始化recyclerView的设置
     */
    private void initRecyclerView() {
        recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        addRecyclerViewData(0);//先显示第0页数据
        myAdapter = new MyAdapter();
        recyclerView.setAdapter(myAdapter);
    }

    /**
     * 模拟为RecyclerView添加数据,pager为当前显示的卡片页
     */
    private void addRecyclerViewData(int pager) {
        data.removeAll(data);
        for (int i = 0; i < 50; i++) {
            data.add("pager=" + pager + ",第" + i + "个item");
        }
    }

    /**
     * 初始化选项卡的数据
     */
    private void initTabLayout() {
        for (int i = 0; i < 10; i++) {
            tabLayout.addTab(tabLayout.newTab().setText("卡片"+i));//添加选项
        }
        //选项卡的切换监听,都在主线程中运行的
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.i("tag", "点击的第"+tab.getPosition()+"个卡片");
                addRecyclerViewData(tab.getPosition());//添加数据
                myAdapter.notifyDataSetChanged();
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.i("tag", "取消了第"+tab.getPosition()+"个卡片的显示");
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                //当前选中的选项被再次点击的时候调用
                Log.i("tag", "第"+tab.getPosition()+"个卡片重新被点击");
            }
        });
    }

    /**
     * 初始化Toolbar的数据
     */
    private void initToolbar() {
        //也可以在布局中设置这些属性,具体见布局文件
        toolbar.setNavigationIcon(R.mipmap.ic_launcher);//设置最左侧图标
        //toolbar.setLogo(R.mipmap.ic_launcher);//设置程序logo图标
        toolbar.setTitle("toolbar标题");
        toolbar.setSubtitle("子标题");
        toolbar.setTitleTextColor(Color.parseColor("#ff0000"));//设置标题的字体颜色
        toolbar.setSubtitleTextColor(Color.parseColor("#00ff00"));//设置子标题的字体颜色
        setSupportActionBar(toolbar); //取代原本的actionbar,继承activity可以不设置,不替换显示不了菜单
        //单击事件需要在setSupportActionBar方法后,因为原本的actionbar也有这个单击事件
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "点击了最左边的图标", Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 如果是继承的AppCompatActivity,取代了原有的actionbar,需要手动的将toolbar中的菜单设置上来
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.main_menu,menu);//将toolbar中的菜单添加上来
        return true;
    }

    /**
     * RecyclerView适配器
     */
    class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new MyViewHolder(getLayoutInflater().inflate(R.layout.item_layout,parent,false));
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            holder.tv.setText(data.get(position));
        }

        @Override
        public int getItemCount() {
            return data.size();
        }

        class MyViewHolder extends RecyclerView.ViewHolder{

            TextView tv;

            public MyViewHolder(View itemView) {
                super(itemView);
                tv = (TextView) itemView.findViewById(R.id.textView);
            }
        }
    }

}

布局文件:activity_main.xml

<!-- CoordinatorLayout:翻译过来就是协调者,其实就是Framelayout的加强版,
    AppBarLayout:继承LinearLayout,支持手势滑动操作,它的作用就是把AppBarLayout包裹的内容都作为AppBar
        也就是都作为活动条的意思,但特别的是可以让它滑出屏幕,这里在该布局中放入Toolbar与TabLayout
    -->
<android.support.design.widget.CoordinatorLayout
    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=".MainActivity">

    <!--标题栏,设置的layout_scrollFlags有如下几种选项:
      scroll: 所有想滚动出屏幕的view都需要设置这个flag-没有设置这个flag的view将被固定在屏幕顶部。
      enterAlways: 这个flag让任意向下的滚动都会导致该view变为可见,适用于快速“返回模式”。
      enterAlwaysCollapsed: 当你的视图已经设置minHeight属性又使用此标志时,
                            你的视图只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
      exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。-->
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!--替换actionbar的布局,位置可以任意,可以插入布局和在代码中插入菜单
       如果是在布局中设置标题和图标,切记引进一个命名空间,然后在该命名空间下设置属性-->
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:background="#ffcccc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways">
        </android.support.v7.widget.Toolbar>
        <!--选项卡,具体的参数信息可以参考前面的文章-->
        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:background="#ffffff"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabIndicatorColor="#0000ff"
            app:tabTextColor="#000000"
            app:tabMode="scrollable"
            app:tabSelectedTextColor="#ff0000">
        </android.support.design.widget.TabLayout>
    </android.support.design.widget.AppBarLayout>

    <!--包含可滑动的布局内容(RecyclerView,NestedScrollView,不支持ListView,ScrollView,ViewPager),但是可以在NestedScrollView中使用
        必须要设置app:layout_behavior="@string/appbar_scrolling_view_behavior" (布局行为)
        属性来告知CoordinatorLayout该组件是带有滑动行为的组件,
        然后CoordinatorLayout在接受到滑动时会通知AppBarLayout中可滑动的Toolbar可以滑出屏幕-->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>

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

说明:由于CoordinatorLayout不支持ViewPager,但是支持NestedScrollView,所以可以把ViewPager放NestedScrollView中就可以了,具体使用见:

可折叠活动条 CollapsingToolbarLayout的使用  与 http://blog.csdn.net/mchenys/article/details/51541306

RecyclerView显示的子布局,item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/textView"
        android:gravity="center"
        android:textSize="20sp"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

</LinearLayout>
View Code

菜单布局,main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <!--作为Toolbar的菜单-->
    <item
        android:id="@+id/menu1"
        android:title="菜单1"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/menu2"
        android:title="菜单2"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/menu3"
        android:title="菜单3"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never"/>
    <item
        android:id="@+id/menu4"
        android:title="菜单4"
        android:icon="@mipmap/ic_launcher"
        app:showAsAction="never"/>
</menu>
View Code

现在来介绍下CoordinatorLayout,CoordinatorLayout是一个增强型的FrameLayout,它的作用就是用来协调其所包裹的子view的手势操作的. 
为了达到上面效果图的手势动画效果,我们必须做如下设置,通过app:layout_scrollFlags=”scroll|enterAlways” 属性来确定哪个组件是可滑动的. 
关于layout_scrollFlags的属性设置,在上面的布局文件中已经描述清楚,这里就不多说了.

同时 ,为了使得Toolbar可以滑动,我们必须还得有个条件,就是CoordinatorLayout布局下包裹一个可以滑动的布局,比如: RecyclerView,NestedScrollView(ListView,ScrollView不支持)具有滑动效果的组件。 
并且还需要给这些组件设置如下属性来告诉CoordinatorLayout,该组件是带有滑动行为的组件,然后CoordinatorLayout在接受到滑动时会通知AppBarLayout 中可滑动的Toolbar可以滑出屏幕了。

效果如下:当ToolBar滚出屏幕的时候,TabLayout固定在屏幕顶部,然后下滑的时候在划出Toolbar.

 

 

手动设置AppBarLayout为展开状态:

appBarLayout.setExpanded(true,true);

 

posted @ 2016-10-06 18:40  ts-android  阅读(7472)  评论(0编辑  收藏  举报