协调布局CoordinatorLayout

Android自5.0之后对UI做了较大的提升。一个重大的改进是推出了MaterialDesign库,而该库的基础即为协调布局CoordinatorLayout,差点儿全部的design控件都依赖于该布局。协调布局的含义。指的是内部控件互相之前的动作关联,比方在A视图的位置发生变化之时。B视图的位置也依照某种规则来变化。仿佛弹钢琴有了协奏曲一般。

使用CoordinatorLayout时。要注意以下几点:
1、导入design库;
2、根布局採用android.support.design.widget.CoordinatorLayout;
3、CoordinatorLayout节点要加入命名空间声明xmlns:app="http://schemas.android.com/apk/res-auto";

CoordinatorLayout继承自ViewGroup,实现效果相似于RelativeLayout。若要指定子视图在整个页面中的位置,有以下几个办法:
1、使用layout_gravity属性,指定子视图在CoordinatorLayout内部的对齐方式。
2、使用app:layout_anchor和app:layout_anchorGravity属性,指定子视图相对于其他子视图的位置。当中app:layout_anchor表示当前以哪个视图做为參照物,app:layout_anchorGravity表示本视图相对于參照物的对齐方式。

3、使用app:layout_behavior属性,指定子视图相对于其他视图的行为,当对方的位置发生变化时,本视图的位置也要随之对应变化。

以下是使用anchor方式定义子视图方位的截图,当中红色方块位于整个页面的右上方:

以下是演示anchor方式的布局文件样例:

<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/cl_main"
android:layout_width="match_parent"
android:layout_height="match_parent" > <LinearLayout
android:id="@+id/ll_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ffff"
android:orientation="vertical" > </LinearLayout> <TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_margin="50dp"
app:layout_anchor="@id/ll_main"
app:layout_anchorGravity="top|right"
android:background="#ff0000" /> </android.support.design.widget.CoordinatorLayout>

悬浮buttonFloatingActionButton

FloatingActionButton是design库提供的一个酷炫button。它继承自ImageButton,。除了图像button的全部功能之外,还提供了以下的其他功能:
1、FloatingActionButton会悬浮在其他视图之上。即使别的视图在布局文件里位于FloatingActionButton后面。
2、在隐藏、显示button上时会播放动画;当中隐藏操作是调用hide方法。显示操作是调用show方法;
3、FloatingActionButton默认会随着Snackbar的出现或消失而动态调整位置。有关Snackbar的说明參见《Android开发笔记(一百二十七)活用提示窗Toast和Snackbar》;

以下是悬浮button自隐藏和显示时的动画效果截图:

以下是悬浮button尾随提示条上移和下移的效果截图:

以下是演示悬浮button的布局文件样例:

<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/cl_main"
android:layout_width="match_parent"
android:layout_height="match_parent" > <LinearLayout
android:id="@+id/ll_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:id="@+id/btn_snackbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:text="显示简单提示条"
android:textColor="@color/black"
android:textSize="17sp" /> <Button
android:id="@+id/btn_floating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:text="隐藏悬浮button"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout> <android.support.design.widget.FloatingActionButton
android:id="@+id/fab_btn"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="20dp"
app:layout_anchor="@id/ll_main"
app:layout_anchorGravity="bottom|right"
android:background="@drawable/float_btn" /> </android.support.design.widget.CoordinatorLayout>

底部弹窗BottomSheetBehavior

design库提供了Snackbar在页面底部弹出提示条。但是Snackbar着实简单。假设我们想在底部弹出一组菜单。Snackbar就无能为力了。

因此,Android又提供了BottomSheetBehavior用来自己定义底部弹窗。只是它并不是一种新控件,而是给现有视图加上几个新属性。就可以实现弹窗与关闭的效果。

这几个新增属性的说明例如以下:
app:behavior_hideable : 指定弹窗是否同意隐藏。
app:behavior_peekHeight : 指定弹窗的预览高度。

app:elevation : 指定弹窗的高程。
app:layout_behavior : 指定弹窗的行为。像底部弹窗固定取值"@string/bottom_sheet_behavior"。

BottomSheetBehavior在代码中使用的方法例如以下所看到的:
from : 从指定视图获取底部弹窗行为。

getState : 获取该行为的状态。
setState : 设置该行为的状态。

取值STATE_EXPANDED表示全然展开。取值STATE_COLLAPSED表示折叠;取值STATE_HIDDEN表示隐藏。
setPeekHeight : 设置弹窗的预览高度,即setState取值STATE_COLLAPSED时设定的折叠高度。

setHideable : 设置弹窗是否同意隐藏。

以下是底部弹窗的演示截图:

以下是使用底部弹窗的布局样例:

<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/cl_main"
android:layout_width="match_parent"
android:layout_height="match_parent" > <LinearLayout
android:id="@+id/ll_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:id="@+id/btn_bottomsheet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:text="显示底部弹窗"
android:textColor="@color/black"
android:textSize="17sp" />
</LinearLayout> <LinearLayout
android:id="@+id/ll_bottom"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#ffaaaa"
app:behavior_hideable="true"
app:behavior_peekHeight="50dp"
app:elevation="5dp"
app:layout_behavior="@string/bottom_sheet_behavior"> <TextView
android:id="@+id/tv_popup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="底部弹窗菜单"
android:textColor="#000000"
android:textSize="17sp"/> </LinearLayout> </android.support.design.widget.CoordinatorLayout>

以下是使用底部弹窗的代码样例:

public class BottomSheetActivity extends AppCompatActivity implements OnClickListener {
private Button btn_bottomsheet;
private BottomSheetBehavior behavior; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottomsheet);
btn_bottomsheet = (Button) findViewById(R.id.btn_bottomsheet);
btn_bottomsheet.setOnClickListener(this); View ll_bottom = (View) findViewById(R.id.ll_bottom);
behavior = BottomSheetBehavior.from(ll_bottom);
//假设马上setState,会报错java.lang.NullPointerException
mHandler.postDelayed(mState, 50);
} @Override
public void onClick(View v) {
if (v.getId() == R.id.btn_bottomsheet) {
if (behavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
btn_bottomsheet.setText("隐藏底部弹窗");
} else {
behavior.setState(BottomSheetBehavior.STATE_HIDDEN);
btn_bottomsheet.setText("显示底部弹窗");
}
}
} private Handler mHandler = new Handler();
private Runnable mState = new Runnable() {
@Override
public void run() {
behavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
}; }

点击下载本文用到的协调布局的project代码

点此查看Android开发笔记的完整文件夹

Android开发笔记(一百三十四)协调布局CoordinatorLayout的更多相关文章

  1. Java开发笔记(三十四)字符串的赋值及类型转换

    不管是基本的char字符型,还是包装字符类型Character,它们的每个变量只能存放一个字符,无法满足对一串字符的加工.为了能够直接操作一连串的字符,Java设计了专门的字符串类型String,该类 ...

  2. 安卓开发笔记(三十四):Material Design框架实现优美的左侧侧滑栏

    首先我们先上图:  下面是主页面的代码,activity_main.xml: <?xml version="1.0" encoding="utf-8"?& ...

  3. OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  4. Java开发笔记(一百三十四)Swing的基本对话框

    桌面程序在运行过程中,时常需要在主界面之上弹出小窗,把某种消息告知用户,以便用户及时知晓并对症处理.这类小窗口通常称作对话框,依据消息交互的过程,可将对话框分为三类:消息对话框.确认对话框.输入对话框 ...

  5. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  6. OpenCV开发笔记(七十四):OpenCV3.4.1+ffmpeg3.4.8交叉编译移植到海思平台Hi35xx平台

    前言   移植opencv到海思平台,opencv支持对视频进行解码,需要对应的ffmpeg支持.   Ffmpeg的移植   Ffmpeg的移植请参考之前的文章:<FFmpeg开发笔记(十): ...

  7. 安卓开发笔记(三十):自定义Button

    在笔者本人看了很多博客和书之后,发现很少博主对于自定义控件能够进行一个比较全面的思路讲解,大多数都是只讲了一些细节,但并没有讲如何把代码进行整体的实现.因此这里讲讲整体的自定义button实现的详细过 ...

  8. Java开发笔记(三十五)字符串格式化

    前面介绍了字符串变量的四种赋值方式,对于简单的赋值来说完全够用了,即便是两个字符串拼接,也只需通过加号把两个目标串连起来即可.但对于复杂的赋值来说就麻烦了,假设现在需要拼接一个很长的字符串,字符串内部 ...

  9. Java开发笔记(三十八)利用正则表达式校验字符串

    前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...

随机推荐

  1. SpringBoot 解决时区问题

    SpringBoot 解决时区问题 1.在启动类加上 @PostConstruct void setDefaultTimezone() { TimeZone.setDefault(TimeZone.g ...

  2. mysql性能测试

    mysqlslap mysql自带的工具使用非常方面: 使用语法如下: # mysqlslap [options] 常用参数 [options] 详细说明: --auto-generate-sql, ...

  3. Python 实现简单的感知机算法

    感知机 随机生成一些点和一条原始直线,然后用感知机算法来生成一条直线进行分类,比较差别 导入包并设定画图尺寸 import numpy as np import matplotlib.pyplot a ...

  4. Java容器-引用数据类型排序+TreeSet、TreeMap底层实现

    目录 1.冒泡排序的实现 2.比较接口(普通数据类型.引用数据类型) 普通数据类型:冒泡排序 引用数据类型:包装类(Integer.String.Character.Date) 自定义类型:实体类:i ...

  5. Web前端面试题小集

    一.一个页面上两个div左右铺满整个浏览器,要保证左边的div一直为100px,右边的div跟随浏览器大小变化(比如浏览器为500,右边div为400,浏览器为900,右边div为800),请写出大概 ...

  6. 【转】为 OSCHINA 聚会搞的一个小抽奖程序

    http://www.oschina.net/code/snippet_12_7605 在线演示: http://www.oschina.net/r.html

  7. .NET(C#)主流的ORM框架

    .NET(C#)主流ORM总揽 SqlSugar (国内) Dos.ORM (国内) Chloe (国内) StackExchange/Dapper (国外) Entity Framework (EF ...

  8. 设计原则:小议 SPI 和 API

    背景 第一次听说 SPI 是阅读<软件框架设计的艺术>,以后陆续在 Log4Net 和 Quartz.Net中发现了以这种形式组织代码的方式,本位给出为什么要区分 SPI 和 API 的一 ...

  9. SQL中关于where后面不能放聚合函数(如sum等)的解决办法

    我们在编写较为复杂的SQL语句的时候,常常会遇到需要将sum()放到where后面作为条件查询,事实证明这样是无法执行的,执行会报[此处不允许使用分组函数]异常. 那么如何解决呢,使用HAVING关键 ...

  10. feedparser win7 python 安装

    要获取订阅源读取当中的内容,Universal Feed Parser提供了非常多的API,这里说下详细的配置. 我的配置环境: win7 + python 2.7.5 步骤: 1.下载feedpar ...