介绍
CoordinatorLayout是一个“加强版”的 FrameLayout,它主要有两个用途:
(1) 用作应用的顶层布局管理器
(2) 通过为子View指定 behavior 实现自定义的交互行为。
在我们做 Material Design 风格的app时通常都使用 CoordinatorLayout 作为布局的根节点,以便实现特定的UI交互行为。
那么现在我们来看看如何用已有的一些控件实现一些常见的布局。
Toolbar + TabLayout 实现 TabLayout 置顶效果
很常见的一种模式是 TabLayout 放在 ToolBar 布局中与其一起置顶在界面上方,而现在的效果是将ToolBar 隐藏而 TabLayout一直置顶在界面上方。
tablayout
如何实现呢?首先所在的 Activity 要使用 AppTheme.NoActionBar 风格主题,之后再编写布局文件。
<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <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:layout_scrollFlags="scroll|enterAlways|snap" app:popupTheme="@style/AppTheme.PopupOverlay"> <!-- toolbar内部布局文件 --> </android.support.v7.widget.Toolbar> <android.support.design.widget.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="@dimen/tab_height" app:tabIndicatorColor="@color/white" app:tabTextColor="@color/white_normal"> </android.support.design.widget.TabLayout> </android.support.design.widget.AppBarLayout> <!-- 主界面布局文件 --> </android.support.design.widget.CoordinatorLayout>
很重要的两点:
浸入式 + CollapsingToolbarLayout
CollapsingToolbarLayout 可以包裹 Toolbar , 当其显示完收缩动画时使 Toolbar 显示在顶端。而我们可以再加入浸入式的效果让 CollapsingToolbarLayout 的背景图突破系统的状态栏使界面更加美观同时也不影响 Toolbar 的显示效果。
浸入式布局
在实现布局文件前要赋予当前的Activity主题为AppTheme.Immersive。
其样式要在 v19 与 v21 分别处理,至于v19之前的 android 版本那就无能为力了。
v19
<style name="AppTheme.Immersive" parent="AppTheme.NoActionBar"> <item name="android:windowTranslucentStatus">true</item> </style>
v21
<style name="AppTheme.Immersive" parent="AppTheme.NoActionBar"> <!--透明导航栏--> <item name="android:statusBarColor">@android:color/transparent</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item> </style>
之后再来看布局文件,包括了 AppBarLayout,CollapsingToolbarLayout 和 Toolbar 这些控件。
同样也是要分为 v19 和 v21 两种布局
v19
<?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.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="220dp" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" app:statusBarScrim="@android:color/transparent" app:titleEnabled="false"> <RelativeLayout android:id="@+id/anime_root" android:layout_width="match_parent" android:layout_height="220dp" app:layout_collapseMode="parallax" app:layout_collapseParallaxMultiplier="0.7"> <!-- 可伸缩背景图布局文件 --> </RelativeLayout> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:layout_marginTop="25dp" app:layout_collapseMode="pin" app:popupTheme="@style/AppTheme.PopupOverlay" app:titleMarginTop="15dp" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <!-- 界面布局文件 --> </android.support.design.widget.CoordinatorLayout>
v21
<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"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="220dp" android:fitsSystemWindows="true" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" app:statusBarScrim="@android:color/transparent" app:titleEnabled="false"> <RelativeLayout android:id="@+id/anime_root" android:layout_width="match_parent" android:layout_height="220dp" android:fitsSystemWindows="true" app:layout_collapseMode="parallax" app:layout_collapseParallaxMultiplier="0.7"> <!-- 可伸缩背景图布局文件 --> </RelativeLayout> <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/AppTheme.PopupOverlay" app:titleMarginTop="15dp" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <!-- 界面布局文件 --> </android.support.design.widget.CoordinatorLayout>
那么重点在哪里呢?
fitsSystemWindows详解:这个一个boolean值的内部属性,让view可以根据系统窗口(如status bar)来调整自己的布局,如果值为true,就会调整view的paingding属性来给system windows留出空间。
Fragment + 不同风格布局
有时候产品要求在一个 Activity 上显示不同的 Fragment 界面,且 Fragment 上的每一个头部样式都不一样,比如说一个是普通情况下的 Toolbar,另一个却是浸入式的可伸缩头部,像简书app的首页
额,我们先不提图中的那个bug,图中的界面主要是两种效果,一个为普通的标题栏+正文,另一个则是浸入式的图片背景+正文。我们也可以利用浸入式的主题来仿照出简书的效果。
各个页面不同样式
第一步要做的是给 Fragment 所在的 Activity 套上 AppTheme.Immersive 浸入式主题样式,之后为 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" android:layout_width="match_parent" android:layout_height="match_parent"> <com.ashokvarma.bottomnavigation.BottomNavigationBar android:id="@+id/bottom_navigation_bar" android:layout_width="match_parent" android:layout_height="56dp" android:layout_gravity="bottom" android:fitsSystemWindows="true"> </com.ashokvarma.bottomnavigation.BottomNavigationBar> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginBottom="56dp" /> </android.support.design.widget.CoordinatorLayout>
无他,就是一个 ViewPager 容器用来加载 Fragment。
书城所在的 Fragment 布局如下:
<?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:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" app:statusBarScrim="@android:color/transparent" app:titleEnabled="false"> <!-- 背景布局 --> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="36dp" android:minHeight="36dp" app:layout_collapseMode="pin" app:popupTheme="@style/AppTheme.PopupOverlay"> <!-- 搜索框布局 --> </android.support.v7.widget.Toolbar> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <!-- 界面主布局 --> </android.support.design.widget.CoordinatorLayout>
布局跟之前的浸入式布局相同,但单单这样布局是有问题的,此时的 Toolbar 会显示在系统的状态栏下。所以我们要修正 Toolbar 的摆放位置,即人为的为其设置 MarginTop 距离。
/** * 修正 Toolbar 的位置 * 在 Android 4.4 版本下无法显示内容在 StatusBar 下,所以无需修正 Toolbar 的位置 * * @param toolbar */ protected void fixToolbar(Toolbar toolbar) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { int statusHeight = getStatusBarHeight(getActivity()); ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); layoutParams.setMargins(0, statusHeight, 0, 0); } } /** * 获取系统状态栏高度 * * @param context * @return */ public int getStatusBarHeight(Context context) { Class<?> c = null; Object obj = null; Field field = null; int x = 0, statusBarHeight = 0; try { c = Class.forName("com.android.internal.R$dimen"); obj = c.newInstance(); field = c.getField("status_bar_height"); x = Integer.parseInt(field.get(obj).toString()); statusBarHeight = context.getResources().getDimensionPixelSize(x); } catch (Exception e1) { e1.printStackTrace(); } return statusBarHeight; }
在每个 Fragment 初始化 Toolbar 时都需要调用这个方法来修正位置。
重点又来了:
Fragment 与 Toolbar 的选项菜单问题
在 Fragment 之间切换的时候很容易遇到 Toolbar 上的菜单无法正确的显示的问题,解决方法也很简单,在 Fragment 的 onCreateView() 方法中添加一行代码:
toolbar.setTitle("title"); ((AppCompatActivity) getActivity()).setSupportActionBar(toolbar); fixToolbar(toolbar); setHasOptionsMenu(true); //重要的一行代码,防止选项菜单错乱
总结
自从 Google 出了 com.android.support:design 包之后,其多样化的定制给 App 应用带来更加酷炫的效果,布局的变化只不过是其中的一部分而已。文章的开头也说了, CoordinatorLayout 不止是带来了布局的变化,也带给了控件更多的UI交互动作。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
本文向大家介绍Android 5.0中CoordinatorLayout的使用技巧,包括了Android 5.0中CoordinatorLayout的使用技巧的使用技巧和注意事项,需要的朋友参考一下 CoordinatorLayout 实现了多种Material Design中提到的滚动效果。目前这个框架提供了几种不用写动画代码就能工作的方法,这些效果包括: *让浮动操作按钮上下滑动,为Snack
左边定宽,右边自适应的两列布局 float + margin 左定宽,设置float:left,右设置margin-left为左边的宽度。 absolute + margin 父元素设置相对定位,左定宽设置绝对定位,右设置margin-left为左边的宽度。 float + overflow 左定宽,设置float:left,右设置overflow 不为 visible 生成BFC。 flex 父
本文向大家介绍基于Android代码实现常用布局,包括了基于Android代码实现常用布局的使用技巧和注意事项,需要的朋友参考一下 关于 android 常用布局,利用 XML 文件实现已经有很多的实例了。但如何利用代码实现呢?当然利用代码实现没有太大的必要,也是不提倡的,但我觉得利用代码实现这些布局,可以更好的了解 SDK API ,所以在此也整理一些,和大家分享一下。 首先看一下,布局所对应的
本文向大家介绍Android开发中常用的一些小技巧,包括了Android开发中常用的一些小技巧的使用技巧和注意事项,需要的朋友参考一下 Activity.startActivities() 常用于在应用程序中间启动其他的Activity. TextUtils.isEmpty() 简单的工具类,用于检测是否为空 Html.fromHtml() 用于生成一个Html,参数可以是一个字符串.个人认为它不
本文向大家介绍关于 angularJS的一些用法,包括了关于 angularJS的一些用法的使用技巧和注意事项,需要的朋友参考一下 AngularJS 事件指令: 和ng-click一样,都是给dom绑定事件的 需要注意的是,使用事件对象的时候,需要在ng-click等指令里传入$event,如: 表单指令 当值发生改变的时候就会有用 有value值的一些个标签,能ng-model的,才能用哟 必
问题内容: 我是Android开发的新手,已经开始创建自己的UI。我看到您可以动态创建它,如下所示(Dynamic Layouts ): 但我也看到netbeans有一个文件 Resources- > layout-> main.xml 。因此,您可以为UI创建XML布局(声明XML布局): 所以我的问题是应该使用哪个?在Android开发中,对动态布局和XML布局有何建议和优缺点? 问题答案: