反编译看的实在有点头疼,于是就仔细研究了一下前一段时间的一篇文章Material Design规范,发现这个东西2014年就出来了,为什么我今年才发现呢..无奈.于是乎,读书查资料,撸出一个Demo来;
Demo主要知识点<解释纯属个人见解>
Toolbar- ->Material Design中推荐用来替代ActionBar的组件
DrawerLayout- ->侧滑菜单的父组件
NavigationView- ->侧滑菜单推荐和DrawerLayout一起组合的使用的菜单组件
FloatingActionButton- ->悬浮按钮
CoordinatorLayout- ->加强版的FrameLayout,拥有部分新特性
Snackbar- ->可交互的Toast(不是替代品)
CardView- ->卡片式布局
AppBarLayout->Toolbar的父组件,封装部分事件
SwipeRefreshLayout- ->下拉刷新组件
CollapsingToolbarLayout- ->只能作为AppBarLayout的直接子布局,用于实现更多效果
RecyclerView- ->ListView的代替品
// 话不多说
1.ToolBar
Toolbar强大之处在于,他不仅继承了ActionBar的所有功能,而且灵活性很高,可以配合其他控件完成一些Material Design的效果
下面我们就来学习一下(首先你需要有一个项目):
- 修改styles文件中的style部分内容.目的是让ActionBar隐藏,可由多种实现方式,这里提供一种.
<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>
- xml文件中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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="@color/colorPrimary"></android.support.v7.widget.Toolbar>
</LinearLayout>
高度为?attr/actionBarSize,也可以自己指定,不过MD规范推荐用这个,同样background也是这个道理
运行
..好难看
-
替换ActionBar
Activity中加入代码
protected void onCreate(Bundle savedInstanceState) {
...
Toolbar toolBar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolBar);
...
}
运行
出现我们的Title了,这个是怎么来的,是我们在Manifest中为application设置的label属性的值.和ActionBar是一样的,现在我们的ToolBar才相当于我们的ActionBar,我们也可以修改这个标题,只需要在Manifest中为当前activity添加一个label属性即可
- ToolBar还有好多用法,自己太单调,结合后面的组件一起来
DrawerLayout
好多应用都有这种效果,比如QQ,XX,XXX好多软件
用MD中推荐了一种做法
- 需要修改xml根布局为DrawerLayout并加入一个FrameLayout和一个TextView如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/drawer_layout"
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:layout_gravity=""
android:background="@color/colorPrimary"></android.support.v7.widget.Toolbar>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:text="然而我就是侧拉菜单" />
</android.support.v4.widget.DrawerLayout>
运行
android:layout_gravity=”start”用来设置滑动菜单在左边还是右边
然而还是有点儿问题,因为用户可能根本不知道有这个菜单,因为只有从屏幕左侧向右滑动才可以,所以我们要如此这般
Activity中
@Override
protected void onCreate(Bundle savedInstanceState) {
...
setSupportActionBar(toolBar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
// 使ActionBar左侧的按钮默认可见 是一个←
actionBar.setDisplayHomeAsUpEnabled(true);
// 修改图标
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_home);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
break;
}
return true;
}
//
然而功能是实现了,但是还是很丑,不过可以的,前面已经说了,有个和DrawerLayout组合用的组件,组合起来用就不丑啦.
NavigationView
- 使用方法很简单,将原本TextView的位置用NavigationView替换了就是了->需要加依赖<-
compile ‘com.android.support:design:25.3.1’
<android.support.design.widget.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/colorPrimary" />
运行之后 效果还是一样,只不过没字了,因为不是TextView,好了NavigationView有两个属性
- app:menu
- app:headerLayout
- 首先我们建立一个menu_nav.xml 肯定在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/menu_nav_1"
android:icon="@drawable/ic_menu_home"
android:title="我是1" />
<item
android:id="@+id/menu_nav_2"
android:icon="@drawable/ic_menu_home"
android:title="我是2" />
</group>
</menu>
group android:checkableBehavior=”single”
这个属性是为了限制单选
- 我们再建立一个nav_header.xml 在layout文件夹中
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/icon_header" />
</LinearLayout>
也是很简单的一个布局
- 为NavigationView设置属性了
<android.support.design.widget.NavigationView
android:layout_width="match_parent"
android:id="@+id/design_navigation_view"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/colorPrimary"
app:headerLayout="@layout/nav_header"
app:menu="@menu/menu_nav" />
这里是app命名空间,所以需要
xmlns:app=”http://schemas.android.com/apk/res-auto”
当然 直接alt+enter也会自动添加
运行
- 为NavigationView菜单项设置点击事件
@Override
protected void onCreate(Bundle savedInstanceState) {
...
if (actionBar != null) {
// 使ActionBar左侧的按钮默认可见 是一个←
actionBar.setDisplayHomeAsUpEnabled(true);
// 修改图标
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_home);
}
mNavigationView = (NavigationView) findViewById(R.id.design_navigation_view);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_nav_1:
case R.id.menu_nav_2:
mDrawerLayout.closeDrawers();
return true;
}
return false;
}
});
}
好了我们继续来,悬浮式按钮
FloatingActionButton
知乎右下角的那个圆型按钮就是了
实现
- xml中我们写在ToolBar下方
<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="@color/colorPrimary"></android.support.v7.widget.Toolbar>
<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="16dp"
android:src="@drawable/ic_menu_home" />
</FrameLayout>
都是老属性,大家一看效果便能明白:
- 基本事件
它也有基本的OnOlick事件,使用方式和普通View相同,不做过多说明
Snackbar
Snackbar不是Toast的替代品,Snackbar只是能够和用户交互而已,但是会自动消失,介于Dialog和Toast之间的组件,使用方式也是介于两者之间;
我们就在FloatingActionButton的事件中显示Snackbar
mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(v, "然而我弹出来了", Snackbar.LENGTH_SHORT).setAction("点我", new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar.make(v, "然而你点我也没用", Snackbar.LENGTH_SHORT).show();
}
}).show();
}
});
运行
咳咳,这里Snackbar把下面的FAB挡住了,我们需要解决这个问题,谷歌为我们创造了这个问题,肯定也有相应的解决办法- ->CoordinatorLayout
CoordinatorLayout
CoordinatorLayout是一个加强版的FrameLayout,可以监听所有子控件的各种事件,然后自动帮我们做出最为合理的相应;
我们把FrameLayout替换为CoordinatorLayout
<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:layout_gravity=""
android:background="@color/colorPrimary"></android.support.v7.widget.Toolbar>
<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="16dp"
android:src="@drawable/ic_menu_home" />
</android.support.design.widget.CoordinatorLayout>
运行
需要注意的是,只有Snackbar传入的第一个参数View是CoordinatorLayout的子组件时,此效果才会生效,因为我们传入的是v,而v是我们的FAB,所以会生效;
CardView
需要依赖
compile ‘com.android.support:cardview-v7:25.3.1’
卡片式布局 ,他可以让页面中的元素看起来就像在卡片中一样,并且能够拥有圆角和投影.
咱们把这个卡片里面装上美女放到RecyclerView中去,放松一下…
美女图片需要加载咱们用Glide
compile ‘com.github.bumptech.glide:glide:3.7.0’
- 首先写一个item布局,顺带着看看CardView的用法
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="5dp"
android:orientation="vertical"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="center_horizontal"
android:textSize="16sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
app:cardCornerRadius=”4dp” 表示圆角的大小
android:elevation=”5dp”表示高度Z轴
数值越大,高度越高,投影范围越大,投影越浅,反之亦然;
CardView本质是一个FrameLayout没啥好的定位方式,咱们就嵌套一个LinearLayout;
之后我们写RecyclerView部分代码,主界面加入RecyclerView
...
</android.support.v7.widget.Toolbar>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
// 此处有FAB 影响妹子美观,删除
...
写好适配器以及在Activity中设置好Manager以及初始化好数据
高能预警:!!!!!!下面会有一长串代码,不想复制的童鞋可以直接跳过
- 首先妹子实体
public class MeiZi implements Serializable {
private String meiZiName;
private int meiZiId;
public MeiZi(String meiZiName, int meiZiId) {
this.meiZiName = meiZiName;
this.meiZiId = meiZiId;
}
public String getMeiZiName() {
return meiZiName;
}
public void setMeiZiName(String meiZiName) {
this.meiZiName = meiZiName;
}
public int getMeiZiId() {
return meiZiId;
}
public void setMeiZiId(int meiZiId) {
this.meiZiId = meiZiId;
}
}
- 适配器
public class MeiZiAdapter extends RecyclerView.Adapter<MeiZiAdapter.MeiZiViewHolder> implements View.OnClickListener {
private List<MeiZi> meiZiList;
private Context mContext;
private OnItemClickListener listener;
public MeiZiAdapter(List<MeiZi> meiZiList, Context mContext) {
this.meiZiList = meiZiList;
this.mContext = mContext;
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
@Override
public MeiZiViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_meizi_list, parent, false);
view.setOnClickListener(this);
return new MeiZiViewHolder(view);
}
@Override
public void onBindViewHolder(MeiZiViewHolder holder, int position) {
MeiZi meiZi = meiZiList.get(position);
Glide.with(mContext).load(meiZi.getMeiZiId()).into(holder.imageView);
holder.textView.setText(meiZi.getMeiZiName());
}
@Override
public int getItemCount() {
return meiZiList.size();
}
@Override
public void onClick(View v) {
if (listener == null)
return;
listener.OnItemClick(v);
}
static class MeiZiViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public MeiZiViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.image);
textView = (TextView) itemView.findViewById(R.id.text);
}
}
public interface OnItemClickListener {
void OnItemClick(View v);
}
}
- Activity中部分代码
...
initMeiZi();
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mManager = new GridLayoutManager(this, 2);
mAdapter = new MeiZiAdapter(meiZiList, this);
mRecyclerView.setLayoutManager(mManager);
mAdapter.setOnItemClickListener(new MeiZiAdapter.OnItemClickListener() {
@Override
public void OnItemClick(View v) {
Snackbar.make(v, "点击了第" + mRecyclerView.getChildAdapterPosition(v) + "个"
, Snackbar.LENGTH_SHORT).show();
}
});
mRecyclerView.setAdapter(mAdapter);
}
private void initMeiZi() {
meiZiList.clear();
for (int i = 0; i < 30; i++) {
Random random = new Random();
int index = random.nextInt(fruits.length);
meiZiList.add(fruits[index]);
}
}
运行
妹子们还是挺好看的.不过咱们可爱的妹子们把咱们的ToolBar遮挡了…无奈,因为CoordinatorLayout本身是一个FrameLayout,怎么解决?用偏移量么?…不要,MD给我们提供了更好的解决办法
AppBarLayout
AppBarLayout是一个垂直的LinearLayout,用它来包裹一下ToolBar再设置一下属性即可
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
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="@color/colorPrimary"></android.support.v7.widget.Toolbar>
</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"></android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>
app:layout_behavior=”@string/appbar_scrolling_view_behavior”
这个,咱们Ctrl点进去看看
android.support.design.widget.AppBarLayout$ScrollingViewBehavior
这么着写,Recycler就会在ToolBar的下方了
不过这还不是AppbarLayout真正炫酷的地方.它给他的子控件提供一个属性,可以让它随着列表的操作做出相应的操作
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways|snap"></android.support.v7.widget.Toolbar>
app:layout_scrollFlags=”scroll|enterAlways|snap”>
说明一下
- scroll –>当RecyclerView向上滚动时,Toolbar会跟着向上动
- enterAlways –>当RecyclerView向下滑动时.ToolBar会跟着向下动并显示
- snap –>当RecyclerView还没有完全隐藏或者显示的时候,自动判断ToolBar的显示状态
大家可以自行运行一下
RecyclerView得刷新吧,下拉刷新,MD也给我们提供了一个组件,目前知乎掘金动用到了这个SwipeRefreshLayout
SwipeRefreshLayout
没啥解释的,代码才是王道
同样也是用它包裹RecyclerView,当然,RecyclerView的部分属性要移到SwipeRefreshLayout上来;
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
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.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
此时运行的话,会这样…
这个圈圈消失不掉.因为我们没有对这个SwipeRefreshLayout进行事件响应,下面我们开始写它的事件响应;
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
// 轮询颜色
mSwipeRefreshLayout.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
initMeiZi();
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
});
这样就能消失了….简单吧,至于下拉加载更多,博主还没有找到适合MD规范的组件,不过这里提供一种实现方法,仅提供代码
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
// newState RecyclerView的滑动状态
// 0 滑动停止
// 1 屏幕没停且手在屏幕上
// 2 屏幕没停 惯性滑动
// 当滑动停止并且屏幕最后一个可见的Item的pos+3大于等于ItemCount的时候 下载更多
if (newState == RecyclerView.SCROLL_STATE_IDLE && mManager.findLastVisibleItemPosition() + 3 >= mManager.getItemCount()) {
initMeiZi(true);
mAdapter.notifyDataSetChanged();
}
}
});
private void initMeiZi(boolean isLoadMore) {
if (!isLoadMore) {
meiZiList.clear();
}
for (int i = 0; i < 25; i++) {
Random random = new Random();
int index = random.nextInt(meiZis.length);
meiZiList.add(meiZis[index]);
}
}
…还剩一个CollapsingToolbarLayout了吧,那咱们就看看妹子的详情;-)
CollapsingToolbarLayout
配合ToolBar和AppBarLayout实现类似QQ空间的样式
高能预警:!!!!!!下面也会有一长串代码,不想复制的童鞋可以直接跳过
具体是详情Act以及跳转的部分代码还有xml
public class MeiZiDetailAct extends AppCompatActivity {
private Toolbar toolbar;
private ImageView imageView;
private TextView textView;
private MeiZi meiZi;
public static void actionStart(Context context, MeiZi fruit) {
Intent intent = new Intent(context, MeiZiDetailAct.class);
intent.putExtra("MEI_ZI", fruit);
context.startActivity(intent);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_meizi_detail);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
imageView = (ImageView) findViewById(R.id.image);
textView = (TextView) findViewById(R.id.text);
meiZi = (MeiZi) getIntent().getSerializableExtra("MEI_ZI");
if (meiZi == null) {
return;
}
Glide.with(this).load(meiZi.getMeiZiId()).into(imageView);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 300; i++) {
stringBuilder.append(meiZi.getMeiZiName() + "_ _" + i + "_ _");
}
textView.setText(stringBuilder);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
跳转部分
mAdapter.setOnItemClickListener(new MeiZiAdapter.OnItemClickListener() {
@Override
public void OnItemClick(View v) {
MeiZiDetailAct.actionStart(MeiZiListAct.this, meiZiList.get(mRecyclerView.getChildAdapterPosition(v)));
}
});
<?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.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="250dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:contentScrim="@color/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
</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="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="35dp"
app:cardCornerRadius="4dp">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<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_menu_home"
app:layout_anchor="@id/app_bar_layout"
app:layout_anchorGravity="bottom|end" />
</android.support.design.widget.CoordinatorLayout>
这个xml有点长,我简单说一下.
CollapsingToolbarLayout
- app:contentScrim=”@color/colorPrimary” 区域折叠以及折叠后 显示的颜色,CollapsingToolbarLayout折叠之后 就是一个ToolBar
- app:layout_scrollFlags=”scroll|exitUntilCollapsed”之前见过,exitUntilCollapsed说的是当折叠完成 就停下 不再移出屏幕
Image
- app:layout_collapseMode=”parallax” 指定它的折叠模式,只有CollapsingToolbarLayout子控件才有的属性, parallax意思是折叠过程中产生错位偏移
- app:layout_collapseMode=”pin” 折叠过程中 形状不变
最下面有一个NestedScrollView,可以响应滚动事件,因为只有滚动才能折叠,类似ScrollView但是ScrollView不支持响应滚动;
FloatingActionButton
- app:layout_anchor=”@id/app_bar_layout” 为FAB指定锚点,使其以锚点为基准显示
- app:layout_anchorGravity=”bottom|end” 以锚点为基准显示的位置
然后我们运行
图录制的不咋地
资源都在源码中,可能和本文格式上有点出入,但是代码大致相同;