ToolBar、CoordinatorLayout、AppBarLayout、CollapsingToolbarLayout
依赖
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
</br>
1、ToolBar
可以设置layout_scrollFlag,以实现折叠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方法中调用setSupportActionBar(toolBar);,设置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做出响应,当用户选择了toolbar的某一项时,就会回调该方法
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.toolBar1:
break;
}
return super.onOptionsItemSelected(item);
}
</br>
** 注意: **
在配置文件中,theme设置的是NoActionBar
ToolBar的简单使用Activity需要继承AppCompatActivity
- ** 但是,由于toolbar默认是居右的,title怎么实现居中么? **
<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,会如图
16dp的content inset所以添加contentInsetStart
title居中参考:
Develop Adding the App Bar
reference Toolbar
2、CoordinatorLayout
组织它众多子view之间互相协作,CoordinatorLayout作为“super-powered FrameLayout”,设置子视图的android:layout_gravity属性控制位置。
CoordinatorLayout 的神奇之处就在于 Behavior 对象。怎么理解呢?CoordinatorLayout使得子view之间知道了彼此的存在,一个子view的变化可以通知到另一个子view,CoordinatorLayout 所做的事情就是当成一个通信的桥梁,连接不同的view,使用 Behavior 对象进行通信。
比如:在CoordinatorLayout中使用AppBarLayout,如果AppBarLayout的子View(如ToolBar、TabLayout)标记了app:layout_scrollFlags滚动事件,那么在CoordinatorLayout布局里其它标记了app:layout_behavior的子View(LinearLayout、RecyclerView、NestedScrollView等)就能够响应(如ToolBar、TabLayout)控件被标记的滚动事件。
3、AppBarLayout
AppBarLayout 是继承LinerLayout实现的一个ViewGroup容器组件,它是为了Material Design设计的AppBar,支持手势滑动操作。默认的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的内容都作为AppBar。如下图所示
APP Bar,以ImageView,ToolBar为共同构成
以ToolBar作为APPBar
实现了隐藏和显示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: 想滚动就必须设置这个, 没有设置,view将被固定在屏幕顶部
- enterAlways:实现quick return效果, 当向下移动时,立即显示View(比如Toolbar)
- enterAlwaysCollapsed:当你的View已经设置minHeight属性又使用此标志时,你的View只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
- exitUntilCollapsed:向上滚动时收缩View,但可以固定Toolbar一直在上面。
- ** 注意:**
- AppBarLayout必须作为Toolbar的父布局容器
- AppBarLayout是支持手势滑动效果的,不过需要跟CoordinatorLayout配合使用
- 为了AppBar可以滚动,需要在CoordinatorLayout里面,放一个带有可滚动的View,只支持NestedScrollView和RecycleView,不支持listview
- 为了AppBar可以滚动,给需要滑动的组件(Toolbar、CollapsingToolbarLayout)设置 app:layout_scrollFlags属性; 给滑动的组件设置app:layout_behavior属性
app:layout_behavior="@string/appbar_scrolling_view_behavior"
</br>
另一种 显示、隐藏toolbar
通过调用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,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。
APP Bar,以ImageView,ToolBar为共同构成代码如下
<?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 - 设置当CollapsingToolbarLayout完全折叠(收缩)后的背景颜色
- expandedTitleMarginStart - 设置扩张时候(还没有收缩时)title向左填充的距离。
- layout_scrollFlags="scroll|exitUntilCollapsed"
2、在ImageView控件中:
- layout_collapseMode
- pin - 当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上。
- parallax - 在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,实现视差滚动效果,通常和layout_collapseParallaxMultiplier(设置视差因子)搭配使用。
- layout_collapseParallaxMultiplier(视差因子) - 设置视差滚动因子,值为:0~1。
3、Toolbar控件中:
- layout_collapseMode(折叠模式):为pin。
5、监听appBarLayout的收缩
使用OnOffsetChangedListener
- verticalOffset==0时,说明是展开的;
- verticalOffset<0,开始收缩了;
- |verticalOffset|==H(AppBarLayout-ToolBar-StatusBar),已经完全收缩了
代码如下
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);
// 状态栏高度
statusBarHeight = frame.top;
}
监听toolbar的收缩
参考:
Android CollapsingToolbarLayout collapse Listener
Android如何获取系统高度、标题栏和状态栏高度
</br>
代码 下载
网友评论