您的位置:首页 > 产品设计 > UI/UE

【Android-UI】关于CoordinatorLayout的使用

2016-08-11 11:05 232 查看
一、介绍

在参考一个项目demo的时候看到了这个控件,于是查阅相关资料对其进行学习使用。

使用AS在创建新项目的时候可以直接创建带有CoordinatorLayout的Activity,如图:



布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.tablle.mytest.testActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />

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

<include layout="@layout/content_test" />

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />

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

布局中的主要三个控件



floating action button 是一个负责显示界面基本操作的圆形按钮。Design library中的FloatingActionButton 实现了一个默认颜色为主题中colorAccent的悬浮操作按钮。

除了一般大小的悬浮操作按钮,它还支持mini size(fabSize="mini")。FloatingActionButton继承自ImageView,你可以使用android:src或者ImageView的任意方法,比如setImageDrawable()来设置FloatingActionButton里面的图标。

二、使用

1、CoordinatorLayout与FloatingActionButton --- Snackbar

SnackBar是DesignSupportLibrary中的一个重要的控件,用于在界面下面提示一些关键信息,跟Toast不同的地方是SnackBar允许用户向右滑动消除它,同时,也允许在SnackBar中设定一个Action,当用户点击了SnackBar里面的按钮的时候,可以进行一些操作,所以,功能绝对是很强大的。



因为包含了可以与snackbar交互的滑动删除与操作按钮,snackbar被看作是比toast更强大的快速反馈机制。但是你会发现他们的API非常相似:

Snackbar
.make(parentLayout, R.string.snackbar_text, Snackbar.LENGTH_LONG)
.setAction(R.string.snackbar_action, myOnClickListener)
.show(); // Don’t forget to show!
你应该注意到了make()方法中把一个View作为第一个参数 - Snackbar试图找到一个合适的父亲以确保自己是被放置于底部。

修改代码,更改Snackbar的默认样式:

public class MainActivity extends AppCompatActivity {

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

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "快点联系我吧,亲~", Snackbar.LENGTH_LONG)
.setAction("ok~", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"Hello,qin~",Toast.LENGTH_SHORT).show();
}
}).show();
}
});
}

}
效果:



FloatingActionButton是最简单的使用CoordinatorLayout的例子,FloatingActionButton默认使用FloatingActionButton.Behavior。

behavior

CoordinatorLayout功能如此强大,而他的神奇之处在于Behavior对象,CoordinatorLayout自己并不控制View,所有的控制权都在Behavior。前面写到了FloatingActionButton.Behavior,AppBarLayout.Behavior, AppBarLayout.ScrollingViewBehavior。 AppBarLayout中有两个Behavior,一个是拿来给它自己用的,另一个是拿来给它的兄弟结点用的。这些Behavior实现了复杂的控制功能。系统的Behavior毕竟有限,我们可以通过自定义的方式来实现自己的Behavior。

通过 CoordinatorLayout.Behavior(YourView.Behavior.class) 来定义自己的Behavior,并在layout 文件中设置 app:layout_behavior=”com.example.app.YourView$Behavior” 来达到效果。

自定义Behavior 需要重写两个方法:

public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency)

public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency)

如下面的例子,实现了点击FloatingActionButton点击旋转90度,并适配Snackbar。

自定义的behavior

public class FabRotateBehavior  extends CoordinatorLayout.Behavior<FloatingActionButton> {

public FabRotateBehavior() {
}

public FabRotateBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}

@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
return dependency instanceof Snackbar.SnackbarLayout;
}

@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
float translationY = getFabTranslationYForSnackbar(parent, child);
float percentComplete = -translationY / dependency.getHeight();
child.setRotation(-90 * percentComplete);
child.setTranslationY(translationY);
return false;
}

private float getFabTranslationYForSnackbar(CoordinatorLayout parent,
FloatingActionButton fab) {
float minOffset = 0;
final List<View> dependencies = parent.getDependencies(fab);
for (int i = 0, z = dependencies.size(); i < z; i++) {
final View view = dependencies.get(i);
if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(fab, view)) {
minOffset = Math.min(minOffset,
ViewCompat.getTranslationY(view) - view.getHeight());
}
}

return minOffset;
}
}
将behavior应用到FlotingActionButton中
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"
app:layout_behavior="com.tablle.newtest.behavior.FabRotateBehavior" />

效果:



2、CoordinatorLayout与AppBarLayout --- TabLayout
 AppBarLayout嵌套TabLayout

修改布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tablle.newtest.MainActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_scrollFlags="scroll|enterAlways" />

<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

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

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email"
app:layout_behavior="com.tablle.newtest.behavior.FabRotateBehavior" />

</android.support.design.widget.CoordinatorLayout>
效果:



为了ToolBar可以滚动,CoordinatorLayout里面,放一个带有可滚动的View.如上的例子,放的是ViewPager,而ViewPager里面是放了RecylerView的,即是可以滚动的View。CoordinatorLayout包含的子视图中带有滚动属性的View需要设置app:layout_behavior属性。例如,示例中Viewpager设置了此属性。

app:layout_behavior="@string/appbar_scrolling_view_behavior"

layout_scrollFlags属性值:

scroll: 所有想滚动出屏幕的view都需要设置这个flag, 没有设置这个flag的view将被固定在屏幕顶部。例如,TabLayout 没有设置这个值,将会停留在屏幕顶部。
enterAlways: 设置这个flag时,向下的滚动都会导致该view变为可见,启用快速“返回模式”。
enterAlwaysCollapsed: 当你的视图已经设置minHeight属性又使用此标志时,你的视图只能已最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。
为了使得Toolbar有滑动效果,必须做到如下三点:
1. CoordinatorLayout作为布局的父布局容器。
2. 给需要滑动的组件设置 app:layout_scrollFlags=”scroll|enterAlways” 属性。
3. 给滑动的组件设置app:layout_behavior属性

注意:

Toolbar:app:layout_scrollFlags="scroll|enterAlways"

ViewPager:app:layout_behavior="@string/appbar_scrolling_view_behavior"

2、CoordinatorLayout与AppBarLayout --- CollapsingToolbarLayout

AppBarLayout嵌套CollapsingToolbarLayout

这种效果在详情页面用的较多,展示个性化内容,图像有强烈的吸引力。这个效果重点使用了CollapsingToolbarLayout 。

CollapsingToolbarLayout可实现Toolbar的折叠效果。CollapsingToolbarLayout的子视图类似与LinearLayout垂直方向排放。

给首页的RecycleView设置Item的点击,然后新建一个详情页面,布局如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="256dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">

<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/header"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6" />

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</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">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp">

<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CardView"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ion LSL Lm mkN JNLKn kNK,M LKNMkln kln klnKL NKLNKLn klnKL N" />

</LinearLayout>

</android.support.v7.widget.CardView>

<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CardView"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ion LSL Lm mkN JNLKn kNK,M LKNMkln kln klnKL NKLNKLn klnKL N" />

</LinearLayout>

</android.support.v7.widget.CardView>

<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CardView"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ion LSL Lm mkN JNLKn kNK,M LKNMkln kln klnKL NKLNKLn klnKL N" />

</LinearLayout>

</android.support.v7.widget.CardView>

<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CardView"
android:textAppearance="@style/TextAppearance.AppCompat.Title" />

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ion LSL Lm mkN JNLKn kNK,M LKNMkln kln klnKL NKLNKLn klnKL N" />

</LinearLayout>

</android.support.v7.widget.CardView>
……
</LinearLayout>

</android.support.v4.widget.NestedScrollView>

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:clickable="true"
android:src="@android:drawable/ic_dialog_email"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end" />

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


CollapsingToolbarLayout 提供以下属性和方法是用: 

1. Collapsing title:ToolBar的标题,当CollapsingToolbarLayout全屏没有折叠时,title显示的是大字体,在折叠的过程中,title不断变小到一定大小的效果。你可以调用setTitle(CharSequence)方法设置title。 

2. Content scrim:ToolBar被折叠到顶部固定时候的背景,你可以调用setContentScrim(Drawable)方法改变背景或者 在属性中使用 app:contentScrim=”?attr/colorPrimary”来改变背景。 

3. Status bar scrim:状态栏的背景,调用方法setStatusBarScrim(Drawable)。还没研究明白,不过这个只能在Android5.0以上系统有效果。 

4. Parallax scrolling children:CollapsingToolbarLayout滑动时,子视图的视觉差,可以通过属性app:layout_collapseParallaxMultiplier=”0.6”改变。值de的范围[0.0,1.0],值越大视察越大。 

5. CollapseMode :子视图的折叠模式,在子视图设置,有两种“pin”:固定模式,在折叠的时候最后固定在顶端;“parallax”:视差模式,在折叠的时候会有个视差折叠的效果。我们可以在布局中使用属性app:layout_collapseMode=”parallax”来改变。

CoordinatorLayout 还提供了一个 layout_anchor 的属性,连同 layout_anchorGravity 一起,可以用来放置与其他视图关联在一起的悬浮视图(如 FloatingActionButton)。本例中使用FloatingActionButton。

通过下面的参数设置了FloatingActionButton的位置,两个属性共同作用使得FAB 浮动按钮也能折叠消失,展现。

app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"

使用CollapsingToolbarLayout实现折叠效果,需要注意3点 

1. AppBarLayout的高度固定 

2. CollapsingToolbarLayout的子视图设置layout_collapseMode属性 

3. 关联悬浮视图设置app:layout_anchor,app:layout_anchorGravity属性

说明:
1、固定高度:

<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="256dp"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
2、layout_collapseMode属性 

<ImageView
android:id="@+id/backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/header"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6" />

<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
3、app:layout_anchor,app:layout_anchorGravity属性

<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/fab_margin"
android:clickable="true"
android:src="@android:drawable/ic_dialog_email"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end" />
4、CollapsingToolbarLayout设置layout_scrollFlags属性

<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
效果如图:



当时遇到个问题,耽误了很久,就是当图片缩回的时候,title的字体会越变越小,完全缩回到Toolbar的时候变的几乎看不清,后来才只要要设置伸展和收缩时title字体的属性:

CollapsingToolbarLayout collapsing_toolbar = (CollapsingToolbarLayout)findViewById(R.id.collapsing_toolbar);
collapsing_toolbar.setTitle("详情页面");

collapsing_toolbar.setCollapsedTitleTextColor(Color.WHITE);

collapsing_toolbar.setExpandedTitleTextAppearance(R.style.ExpandedAppBar);//伸展
collapsing_toolbar.setCollapsedTitleTextAppearance(R.style.CollapsedAppBar);//收缩
<style name="ExpandedAppBar" parent="@android:style/TextAppearance.Medium">
<item name="android:textSize">28sp</item>
<item name="android:textColor">#EE00EE</item>
<item name="android:textStyle">bold</item>
</style>

<style name="CollapsedAppBar" parent="@android:style/TextAppearance.Medium">
<item name="android:textSize">24sp</item>
<item name="android:textColor">@color/white</item>
<item name="android:textStyle">normal</item>
</style>


关于CoordinatorLayout的使用大致如上,其中主要参考了其他几篇博客:

1、android CoordinatorLayout使用:http://blog.csdn.net/xyz_lmn/article/details/48055919

2、CoordinatorLayout与滚动的处理:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0717/3196.html

3、Android开发学习之路-SnackBar使用心得:http://www.cnblogs.com/Fndroid/p/5232358.html

4、TabLayout的简单使用:http://blog.csdn.net/chenguang79/article/details/48804125

5、Android的材料设计兼容库(Design Support Library):http://www.jcodecraeer.com/a/anzhuokaifa/developer/2015/0531/2958.html?mType=Group

6、Android Design Support Library使用详解:http://www.tuicool.com/articles/RnAneuB
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息