ToolBar、CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout
依賴
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
</br>
1、ToolBar
可以設(shè)置layout_scrollFlag,以實現(xiàn)折疊AppBar的效果
1、 布局文件
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:elevation="4dp"
app:title="title"
app:subtitle="subTitle"
app:logo="@mipmap/ic_launcher"
android:background="@color/colorPrimary"/>
2、 在onCreate方法中調(diào)用setSupportActionBar(toolBar);,設(shè)置toolbar作為AppBar
Toolbar toolBar= (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolBar);
3、 定義一個menu資源文件,定義ToolBar的action樣式
<?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">
<item
android:id="@+id/toolBar2"
android:icon="@drawable/tool_bar_2"
android:title="@string/app_name"
app:showAsAction="never" />
</menu>
- showAsAction:
- ifRoom,如果有足夠的空間,該item顯示在AppBar上
- never,總是不顯示在AppBar上,顯示在overflow menu中
- always,顯示在AppBar上
4、 在onCreateOptionsMenu添加menu的布局文件
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_tool_bar,menu);
return super.onCreateOptionsMenu(menu);
}
5、 在onOptionsItemSelected中,對toolbar做出響應(yīng),當(dāng)用戶選擇了toolbar的某一項時,就會回調(diào)該方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.toolBar1:
break;
}
return super.onOptionsItemSelected(item);
}
</br>
** 注意: **
在配置文件中,theme設(shè)置的是NoActionBar
Activity需要繼承AppCompatActivity

- ** 但是,由于toolbar默認是居右的,title怎么實現(xiàn)居中么? **
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:contentInsetStart="0dp">
<TextView
android:textColor="@android:color/white"
android:text="首頁"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v7.widget.Toolbar>
但是由于toolbar有一個16dp的content inset,會如圖

所以添加contentInsetStart

參考:
Develop Adding the App Bar
reference Toolbar
2、CoordinatorLayout
組織它眾多子view之間互相協(xié)作,CoordinatorLayout作為“super-powered FrameLayout”,設(shè)置子視圖的android:layout_gravity屬性控制位置。
CoordinatorLayout 的神奇之處就在于 Behavior 對象。怎么理解呢?CoordinatorLayout使得子view之間知道了彼此的存在,一個子view的變化可以通知到另一個子view,CoordinatorLayout 所做的事情就是當(dāng)成一個通信的橋梁,連接不同的view,使用 Behavior 對象進行通信。
比如:在CoordinatorLayout中使用AppBarLayout,如果AppBarLayout的子View(如ToolBar、TabLayout)標(biāo)記了app:layout_scrollFlags滾動事件,那么在CoordinatorLayout布局里其它標(biāo)記了app:layout_behavior的子View(LinearLayout、RecyclerView、NestedScrollView等)就能夠響應(yīng)(如ToolBar、TabLayout)控件被標(biāo)記的滾動事件。
3、AppBarLayout
AppBarLayout 是繼承LinerLayout實現(xiàn)的一個ViewGroup容器組件,它是為了Material Design設(shè)計的AppBar,支持手勢滑動操作。默認的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的內(nèi)容都作為AppBar。如下圖所示


實現(xiàn)了隱藏和顯示AppBar
代碼如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frameLayout"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.liyi.loadmorelistview.MyChildActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="@+id/myToolBar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/colorAccent"
android:elevation="4dp"
app:title="haha"
app:logo="@drawable/tool_bar_1"
app:layout_scrollFlags="scroll|enterAlways"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="10dp"/>
</android.support.design.widget.CoordinatorLayout>
- ** layout_scrollFlags:**
- scroll: 想滾動就必須設(shè)置這個, 沒有設(shè)置,view將被固定在屏幕頂部
- enterAlways:實現(xiàn)quick return效果, 當(dāng)向下移動時,立即顯示View(比如Toolbar)
- enterAlwaysCollapsed:當(dāng)你的View已經(jīng)設(shè)置minHeight屬性又使用此標(biāo)志時,你的View只能以最小高度進入,只有當(dāng)滾動視圖到達頂部時才擴大到完整高度。
- exitUntilCollapsed:向上滾動時收縮View,但可以固定Toolbar一直在上面。
- ** 注意:**
- AppBarLayout必須作為Toolbar的父布局容器
- AppBarLayout是支持手勢滑動效果的,不過需要跟CoordinatorLayout配合使用
- 為了AppBar可以滾動,需要在CoordinatorLayout里面,放一個帶有可滾動的View,只支持NestedScrollView和RecycleView,不支持listview
- 為了AppBar可以滾動,給需要滑動的組件(Toolbar、CollapsingToolbarLayout)設(shè)置 app:layout_scrollFlags屬性; 給滑動的組件設(shè)置app:layout_behavior屬性
app:layout_behavior="@string/appbar_scrolling_view_behavior"
</br>
另一種 顯示、隱藏toolbar
通過調(diào)用getSupportActionBar(),得到ActionBar,使用它的的show()/hide()方法顯示或隱藏app bar
ActionBar actionBar=getSupportActionBar();
int touchSlop= ViewConfiguration.get(this).getScaledTouchSlop();
loadMoreListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
int currentY= (int) ev.getY();
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
preY= currentY;
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if(preY-currentY>touchSlop){
actionBar.hide();
}else if(currentY-preY>touchSlop){
actionBar.show();
}
break;
}
return false;
}
});
4、CollapsingToolbarLayout
CollapsingToolbarLayout作用是提供了一個可以折疊的Toolbar,它繼承至FrameLayout,給它設(shè)置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在響應(yīng)layout_behavior事件時作出相應(yīng)的scrollFlags滾動事件(移除屏幕或固定在屏幕頂端)。

代碼如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frameLayout"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.liyi.loadmorelistview.MyChildActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="#a0000000">
<ImageView
android:src="@drawable/ic_1"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_collapseParallaxMultiplier="0.5"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="@+id/myToolBar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:elevation="4dp"
app:title="haha"
app:layout_collapseMode="pin"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
...
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
1、在CollapsingToolbarLayout中
- contentScrim - 設(shè)置當(dāng)CollapsingToolbarLayout完全折疊(收縮)后的背景顏色
- expandedTitleMarginStart - 設(shè)置擴張時候(還沒有收縮時)title向左填充的距離。
- layout_scrollFlags="scroll|exitUntilCollapsed"
2、在ImageView控件中:
- layout_collapseMode
- pin - 當(dāng)CollapsingToolbarLayout完全收縮后,Toolbar還可以保留在屏幕上。
- parallax - 在內(nèi)容滾動時,CollapsingToolbarLayout中的View(比如ImageView)也可以同時滾動,實現(xiàn)視差滾動效果,通常和layout_collapseParallaxMultiplier(設(shè)置視差因子)搭配使用。
- layout_collapseParallaxMultiplier(視差因子) - 設(shè)置視差滾動因子,值為:0~1。
3、Toolbar控件中:
- layout_collapseMode(折疊模式):為pin。
5、監(jiān)聽appBarLayout的收縮
使用OnOffsetChangedListener
- verticalOffset==0時,說明是展開的;
- verticalOffset<0,開始收縮了;
- |verticalOffset|==H(AppBarLayout-ToolBar-StatusBar),已經(jīng)完全收縮了
代碼如下
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (Math.abs(verticalOffset) >= mCollapsingToolbarLayout.getHeight() - mToolbar.getHeight()-statusBarHeight) {
//toolBar在這里收縮了
}
}
});
---
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Rect frame = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
// 狀態(tài)欄高度
statusBarHeight = frame.top;
}

參考:
Android CollapsingToolbarLayout collapse Listener
Android如何獲取系統(tǒng)高度、標(biāo)題欄和狀態(tài)欄高度
</br>
代碼 下載