Material Design越来越流行了,然而从来没有人整理一份比较好的MD 学习文档,而自己也不怎么熟悉,所以这篇文档就诞生了。
声明: 本文是参考郭神出版的《Android第二行代码》第12章Material Design实战编写,在此基础上做了一些取舍与提起。
转载请标明出处:
http://blog.csdn.net/u014702332/article/details/53731511
本文出自:【扫地僧的博客】
1. ToolBar
使用ToolBar需要注意以下几点
1. 主题需要修改一下,需要继承NoActionBar,而不要用DarkActionBar,这样会导致ActionBar重复,程序崩溃
2. 颜色样式 :
1. colorPrimary 指定标题栏背影色
2. colorPrimaryDrak 指定状态栏颜色
3. textColorPrimary 指定标题文字颜色
4. windowBackground 背景色
5. navigationBarColor 指定状态导航条颜色
6. colorAccent 比较特殊,指定浮动按钮颜色
<!--<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
3. 注意引用主题 theme popupTheme
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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.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/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
/>
</FrameLayout>
看起来非常单调,这个时候我要插入按钮了。
4.插入菜单按钮
<?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/back_up"
android:icon="@drawable/ic_backup"
android:title="back up"
app:showAsAction="always"
/>
<item
android:id="@+id/delete"
android:icon="@drawable/ic_delete"
android:title="delete"
app:showAsAction="ifRoom"
/>
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="settings"
app:showAsAction="never"
/>
</menu>
- always 表示永远显示,如果屏幕空间不够则不显示
- ifRoom 表示屏幕空间足够的情况下显示在ToolBar中,不够就显示在菜单中。
- never 则表示永远显示在菜单中。
- 注意 ToolBar中的action按钮只会显示按钮,菜单中的action按钮,只会显示文字
5.菜单的点击事件
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.back_up:
Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this, "You clicked Settings", Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
当然ToolBar功能远不止这些,我这里只是列出常用的功能。一般项目够用。
2. 滑动菜单
2.1 DrawerLayout
用法:首先他是一个布局,在布局中允许放入2个直接子控件,第一个子控件是主屏幕显示的内容,第二个子控件是滑动菜单中显示的内容
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<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/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</FrameLayout>
<TextView
android:id="@+id/tv_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:text="this is menu"
android:textSize="30sp"
android:background="#FFF"
/>
</android.support.v4.widget.DrawerLayout>
这里需要指定下TextView的 android:layout_gravity=”start” 告诉滑动菜单是在屏幕左边,还是右边,left,表示在左边,right在右边,这里我用start,会根据系统语言来从左往右。
但是这样弄完还有一个缺陷,用户可能不知道有这个侧滑菜单,所以我们需要添加一个按钮来告诉用户,官方推荐是在导航栏加入一个按钮。
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBar actionBar = getSupportActionBar();
if (null != actionBar){
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
break;
2.2 NavigationView
但上面的菜单栏显示与我们实际想要的效果还差很完,还好官方提供了Navigation控件,让我们很好的把菜单栏处理一下,几行代码就可以集成。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<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/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_gravity ="start"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/header_layout"
/>
</android.support.v4.widget.DrawerLayout>
官方提供了NavigationView控件,我们只需要指定app:menu与app:headerLayout就可以设置菜单栏与头部栏目。
nav_menu布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_call"
android:icon="@drawable/nav_call"
android:title="call" />
<item
android:id="@+id/nav_friends"
android:icon="@drawable/nav_friends"
android:title="friends" />
<item
android:id="@+id/nav_location"
android:icon="@drawable/nav_location"
android:title="location" />
<item
android:id="@+id/nav_mail"
android:icon="@drawable/nav_mail"
android:title="mail" />
<item
android:id="@+id/nav_task"
android:icon="@drawable/nav_task"
android:title="task" />
</group>
</menu>
以及header_layout.xml布局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="?attr/colorPrimary"
android:padding="10dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/icon_image"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_centerInParent="true"
android:src="@drawable/nav_icon" />
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="tonygreendev@gmail.com"
android:textColor="#FFF"
android:textSize="14sp" />
<TextView
android:id="@+id/mail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/username"
android:text="Tony Green"
android:textColor="#FFF"
android:textSize="14sp" />
</RelativeLayout>
3.悬浮按钮和可交互提示
3.1 FloatingActionButton
这个按钮感觉用处好像和普通按钮没有多大区别,不知道官方为什么会弄这个这样的按钮,完全必要似的啊,但不管吧,也给大家看一下
这里面布局文件有一个属性 android:elevation=”8dp” 指定高度值,高度值越大,投资范围越大,感觉没有什么用似的。直接用默认的就够了。
直接上代码吧:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<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/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@drawable/ic_done"
android:layout_gravity="bottom|end"
android:elevation="8dp"
/>
</FrameLayout>
final FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(A12Activity.this, "Fab click", Toast.LENGTH_SHORT).show();
}
});
3.2 Snackbar
首先要明确的是SnackBar并不是Toast的替代器,他们两者之间有不同的应用场景,Toast的作用是告诉用户现在发生了什么事件,但同时用户只能被动接收这个事情,而SnackBar除了有Toast显示 的功能外,还可以在这基础上做其它的操作,打比方,我删除了一条数据,用SnackBar可以撤销这个操作。
具体用法如下,非常简单:
Snackbar.make(view,"Data delete!",Snackbar.LENGTH_LONG)
.setAction("撤销",new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"撤销了",Snackbar.LENGTH_LONG).show();
}
}).show();
感觉比Toast好看些,另外如果你需要在这基础上作撤销操作,可以setAction。 个人感觉这个setAction并无卵用。
另外我们这个时候发现,SnackBar弹出View把悬浮按钮挡住了,效果不好看,好在Material Design给出了解决方案,这就是,CoordinatorLayout
3.3 CoordinatorLayout
CoordinatorLayout 可以说是一个加强版的FrameLayout,在普通情况下的作用和FrameLayout基本一致,事实上CoordinatorLayout可以监听其所有了控件的各种事件,然后自动帮助我们做出最为合理的响应。举个简单例子,弹出SnackBar提示将悬浮按钮遮挡住了,如果我们让CoordinatorLayout监听到SnackBar的弹出事件,那么它会自动将内部的FloatingActionButton身上偏移,从而确保不会被SnackBar遮挡.
直接用CoordinatorLayout来替换FrameLayout就好了:
...
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<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/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@drawable/ic_done"
android:layout_gravity="bottom|end"
android:elevation="8dp"
/>
</android.support.design.widget.CoordinatorLayout>
...
下面我写了两份基本相同的代码SnackBar中传入的第一个参数,做了改动,如果用drawerLayout,,他不是CoordinatorLayout的子控件,所以无法坚挺变化,这个时候悬浮按钮还是会被挡住。
Snackbar.make(drawerLayout,"Data delete!",Snackbar.LENGTH_LONG)
.setAction("撤销",new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(drawerLayout,"撤销了",Snackbar.LENGTH_LONG).show();
}
}).show();
Snackbar.make(view,"Data delete!",Snackbar.LENGTH_LONG)
.setAction("撤销",new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"撤销了",Snackbar.LENGTH_LONG).show();
}
}).show();
4. 卡片式布局
4.1 CardView
CardView也是一个FrameLayout,只是额外提供了圆角和阴影等效果。这里没有什么好讲的,贴代码吧。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="4dp"
android:elevation="5dp"
>
<TextView
android:id="@+id/tv_info"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v7.widget.CardView>
app:cardCornerRadius属性指定卡片圆角的弧度,数值越大,弧度越大,另外还可以通过app:elevation属性来指定卡片的高度,高度数值越大,投影ailfbn越大,但是投影效果越淡,高度值越小,投影范围也越小,但是投影效果越浓。
4.2 AppBarLayout
上面会造成RecyclerView把ToolBar挡住,由于RecyclerView和ToolBar都是放在CoordinatorLayout中的,我们知道CoordinatorLayout就是一个加强版的FrameLayout,在不进行明确定位的情况下,默认都会放在左上角,从而产生遮挡。由于我们使用的是CoodinatorLayout,而不是FrameLayout所以我们有更加巧妙的解决办法。
好在官方也给出方案使用AppBarLayout,它实际上是一个垂直方向的LinearLayout,它在内部做了很多滚动事件的封装,并应用了Material Design设计理念
我们现在来解决之前覆盖的问题
- 将ToolBar嵌套到AppBarLayout中,
- 给RecyclerView指定一个布局行为, app:layout_behavior=”@string/appbar_scrolling_view_behavior”。
- 但这还没有完,还需要在ToolBar中添加一个属性 app:layout_scrollFlags=”scroll|enterAlways|snap”
- scroll 表示当RecyclerView身上滚动的时候,ToolBar会跟着向上滚动并实现隐藏
- enterAlways 表示当RecyclerView向下滚动的时候,ToolBar会跟着一起向下滚动,并重新显示
- snap表示当ToolBar还没有完全隐藏或者显示的时候,会根据当前滚动的距离,自动选择隐藏还是显示
代码如下:
<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.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
...
5 下拉刷新
这个控件算是我们比较常用的控件了,但这里我是需要再做一下说明
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
这里需要注意一下由于RecyclerView变成了SwipeRefreshLayout的子控件了,所以之前使用的app:layout_behavior 声明布局行为也要列表SwipeRefreshLayout中才行
这里我需要说明几个SwipeRefreshLayout所用到的方法
- setColorSchemeResources(R.color.colorPrimary); 来设置下拉刷新的颜色
- setOnRefreshListener 来做下拉刷新监听。
- 最后需要设置setRefreshing(false) 来结束刷新事件,并隐藏刷新进度条。
代码如下:
private SwipeRefreshLayout swipeRefresh;
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefresh.setColorSchemeResources(R.color.colorPrimary);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshFruits();
}
});
}
private void refreshFruits() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
initFruits();
adapter.notifyDataSetChanged();
swipeRefresh.setRefreshing(false);
}
});
}
}).start();
}
6 可折叠式标题栏
6.1 CollapsingToolBarLaout
- 顾名思义 CollapsingToolBarLayout是一个作用于ToolBar基础之上的布局,他不能独立存在的,
- 它在设计的时候就被限定只能作为AppBarLayout的直接子布局来使用,而AppBarLayout又必须是CoodinatorLayout的子布局。
所以我们可以这么表现他们的层级
CoodinatorLayout
AppBarLayout
CollapsingToolBarLayout
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="exitUntilCollapsed|scroll"
>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout> inatorLayout>
对上述代码解释
- android:theme 指定了一个主题,
- app:contentScrim=”?attr/colorPrimary” 用于指定CollapsingToolbarLayout在趋于折叠状态以驻折叠之后的背影色,其实,CollapsingToolbarLayout 在折叠之后就是一个普通的ToolBar,那么背景色应该是colorPrimary
- app:layout_scrollFlags=”exitUntilCollapsed|scroll” scroll表示CollapsingToolbarLayout会随着滚动完成折叠之后留在界面上,不再移出屏幕。4
另外:
<?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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="250dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="exitUntilCollapsed|scroll"
>
<ImageView
android:id="@+id/iv_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
/>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
- 我们可以看到CollapsingToolbarLayout中定义了一个ImageView和Toolbar也就意味着,这个高级版的标题将是由普通的标题栏加上图片组合而成的。
- app:layout_collapseMode=”” 指定成pin表示在折叠的过程中位置始终保持不变,而指定成parallax表示会在折叠过程中产生一定的错位偏移。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fruit);
Intent intent = getIntent();
String fruitName = intent.getStringExtra(FRUIT_NAME);
int fruitImageId = intent.getIntExtra(FRUIT_IMAGE_ID, 0);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
ImageView fruitImageView = (ImageView) findViewById(R.id.fruit_image_view);
TextView fruitContentText = (TextView) findViewById(R.id.fruit_content_text);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
collapsingToolbar.setTitle(fruitName);
Glide.with(this).load(fruitImageId).into(fruitImageView);
String fruitContent = generateFruitContent(fruitName);
fruitContentText.setText(fruitContent);
}
private String generateFruitContent(String fruitName) {
StringBuilder fruitContent = new StringBuilder();
for (int i = 0; i < 500; i++) {
fruitContent.append(fruitName);
}
return fruitContent.toString();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
说明
- collapsingToolbar.setTitle()设置标题,
- 获取ActionBar,并且使 actionBar.setDisplayHomeAsUpEnabled(true); 因为默认图标就是一个返回剪头,所以无需另外设置。
6.2 充分利用系统状态栏空间
我们发现背景图片与系统的状态栏总有一些不搭的感觉,这时我们可以融合一下就好了。
只给ImageView设置
<?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:orientation="vertical"
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="250dp"
android:fitsSystemWindows="true"
>
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="exitUntilCollapsed|scroll"
android:fitsSystemWindows="true"
>
<ImageView
android:id="@+id/iv_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:src="@drawable/nav_friends"
/>
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
为了图片与状态栏融合需要做以下几条:
- 把Imageview以及其父控件的属性 android:fitsSystemWindows=”true” 全部设置为true
- 还必须把程序的主题中状态栏颜色指定成透明色,android:statusBarColor 属性指定成透明 @android:color/transparent就可以,但问题在于android:statusBarColor的属性是从API21,也就是5.0系统 才有的。如果实现差异性功能呢。
右击res目录-》new–>Directory创建values-v21目录 然后创建一个styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="FruitActivityTheme" parent="AppTheme">
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
</resources>
专门指定了一个FruitActivityTheme主题,给FruitActivity使用。由于values-v21目录只有Android5.0及以上系统才会读取,因此不会有问题。
另外还需要兼容5.0以前的版本,因为5.0之前的系统无法指定状态栏颜色,因此wftcbn不用设置
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="FruitActivityTheme" parent="AppTheme">
</style>
</resources>
注:效果图片是事后才补上的,mac上没有找到好的做Gif图工具,当时就没有做,另外gif图片比较大,后面几张图不怎么好看,凑合着看一下吧