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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM