[置顶] Android的材料设计兼容库(Design Support Library)
android,library,设计,design2016-11-25
一.CoordinatorLayout(协调布局)
CoordinatorLayout作为“super-powered FrameLayout”基本实现两个功能:
1、作为顶层布局
2、调度协调子布局
CoordinatorLayout是一个非常强大的控件,它接管了child组件之间的交互。
二:悬浮操作按钮 Floating Action Button
floating action button 是一个负责显示界面基本操作的圆形按钮。Design library中的FloatingActionButton 实现了一个默认颜色为主题中colorAccent的悬浮操作按钮。
效果图:
代码
<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=".MainActivity">
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="30dp"
android:src="@android:drawable/ic_dialog_email"
android:layout_gravity="bottom|right"/>
</android.support.design.widget.CoordinatorLayout>
除了一般大小的悬浮操作按钮,它还支持mini size(fabSize=”mini”)。FloatingActionButton继承自ImageView,你可以使用android:src或者ImageView的任意方法,比如setImageDrawable()来设置FloatingActionButton里面的图标。
三,SnackBar(升级版的Toast)
为一个操作提供轻量级的,快速的反馈是使用snackbar的最好时机。snackbar显示在屏幕的底部,包含了文字信息与一个可选的操作按钮。在指定时间结束之后自动消失。另外,用户还可以在超时之前将它滑动删除。
效果图:
代码:
Snackbar.make(view,"点击了FloatingActionButton",Snackbar.LENGTH_SHORT)
.setAction("Hello SnackBar", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this,"点击了Snackbar",Toast.LENGTH_SHORT).show();
}
})
.show();
因为我这里使用CoordinatorLayout作为父布局,floatingActionButton以动画效果进入的时候自动向上移动让出位置,并且在floatingActionButton动画地消失的时候回到原来的位置,不需要额外的代码。
你应该注意到了make()方法中把一个View作为第一个参数 - Snackbar试图找到一个合适的父亲以确保自己是被放置于底部。
四:TabLayout:
Design library的TabLayout 既实现了固定的选项卡 - view的宽度平均分配,也实现了可滚动的选项卡 - view宽度不固定同时可以横向滚动。
它可以使tab的选中事件能更新ViewPager,同时ViewPager的页面改变能更新tab的选中状态。
效果图:
代码:
activity_main
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
app:tabGravity="fill"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
/>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ffffff"
/>
</LinearLayout>
关于TabLayout的tabMode和tabGrabity属性:
TabGravity:放置Tab的Gravity,有GRAVITY_CENTER 和 GRAVITY_FILL两种效果。顾名思义,一个是居中,另一个是尽可能的填充(注意,GRAVITY_FILL需要和MODE_FIXED一起使用才有效果)
TabMode:布局中Tab的行为模式(behavior mode),有两种值:MODE_FIXED 和 MODE_SCROLLABLE。
MODE_FIXED:固定tabs,并同时显示所有的tabs。
MODE_SCROLLABLE:可滚动tabs,显示一部分tabs,在这个模式下能包含长标签和大量的tabs,最好用于用户不需要直接比较tabs。
MainActivity
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import java.util.ArrayList;
import static android.support.design.widget.TabLayout.*;
public class MainActivity extends AppCompatActivity {
Context context;
ViewPager viewPager;
TabLayout tabLayout;
ArrayList<View> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context=this;
initView();
}
public void initView(){
list=new ArrayList<View>();
LayoutInflater inflater= LayoutInflater.from(context);
View view1=inflater.inflate(R.layout.page1,null);
View view2=inflater.inflate(R.layout.page2,null);
View view3=inflater.inflate(R.layout.page3,null);
list.add(view1);list.add(view2);list.add(view3);
viewPager= (ViewPager) findViewById(R.id.viewPager);
tabLayout= (TabLayout) findViewById(R.id.tabLayout);
MyAdapter adapter=new MyAdapter();
viewPager.setAdapter(adapter);
//与ViewPager建立联系
tabLayout.setupWithViewPager(viewPager);
}
public class MyAdapter extends PagerAdapter{
private String[] titles = new String[]{"Tab1", "Tab2", "Tab3"};
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public int getCount() {
return list.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
@Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView(list.get(position));
}
@Override
public Object instantiateItem(View container, int position) {
((ViewPager) container).addView(list.get(position));
return list.get(position);
}
}
}
注意:上面的Tab标签只有在adapter中重写getPageTitle方法才会显示tab
五、AppBarLayout
详情参考:http://www.open-open.com/lib/view/open1472718470375.html
效果图:
布局代码:
<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/coordinator_layout"
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:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="@+id/toolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#30469b"
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:background="#30469b"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabSelectedTextColor="#ff0000"
app:tabTextColor="#ffffff" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
MainActivity:
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import static android.support.design.widget.TabLayout.*;
public class MainActivity extends AppCompatActivity {
Context context;
ViewPager viewPager;
TabLayout tabLayout;
ArrayList<View> list;
Toolbar toolbar;
RecyclerView recyclerView;
ArrayList<String> strings=new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
context=this;
initView();
}
public void initData(){
for (int i=0;i<30;i++){
strings.add(i+"");
}
}
public void initView(){
list=new ArrayList<View>();
LayoutInflater inflater= LayoutInflater.from(context);
View view1=inflater.inflate(R.layout.page1,null);
View view2=inflater.inflate(R.layout.page2,null);
View view3=inflater.inflate(R.layout.page3,null);
list.add(view1);list.add(view2);list.add(view3);
recyclerView= (RecyclerView)view1. findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(context,LinearLayoutManager.VERTICAL,false));
RecyclerAdapter adapter1=new RecyclerAdapter();
recyclerView.setAdapter(adapter1);
viewPager= (ViewPager) findViewById(R.id.viewpager);
tabLayout= (TabLayout) findViewById(R.id.tabLayout);
toolbar= (Toolbar) findViewById(R.id.toolBar);
setSupportActionBar(toolbar);
MyAdapter adapter=new MyAdapter();
viewPager.setAdapter(adapter);
//与ViewPager建立联系
tabLayout.setupWithViewPager(viewPager);
}
public class MyAdapter extends PagerAdapter{
private String[] titles = new String[]{"Tab1", "Tab2", "Tab3"};
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public int getCount() {
return list.size();
}
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
@Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView(list.get(position));
}
@Override
public Object instantiateItem(View container, int position) {
((ViewPager) container).addView(list.get(position));
return list.get(position);
}
}
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder>{
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView=LayoutInflater.from(parent.getContext()).inflate(R.layout.page_item,parent,false);
ViewHolder viewHolder=new ViewHolder(itemView);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.tv_item.setText(strings.get(position));
}
@Override
public int getItemCount() {
return strings.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView tv_item;
public ViewHolder(View itemView) {
super(itemView);
tv_item= (TextView)itemView.findViewById(R.id.tv_item);
}
}
}
}
六,TextInputLayout(EditText升级版):
TextInputLayout控件和LinearLayout完全一样,它只是一个容器。跟ScrollView一样,TextInputLayout只接受一个子元素。子元素需要是一个EditText元素。
众所周知EditText有一个hint属性,在为输入任何东西 时候,hint会默认显示,一点我们输入,hint则影藏,TextInputLayout则完全解决了这个问题,hint显示在EditText上方。
包含在TextInputLayout中的EditText如果InputType是TextPaswrod,系统会帮你添加一个显示或者隐藏密码的控件在EditText末尾
TextInputLayout有一个setError()方法可以监听当前输入的数据是否符合要求去验证错误。
效果图:
布局代码:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:id="@+id/usernameWrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:hint="密码"
android:inputType="textPassword"
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
七、BottomNavigationBar(导航控制)
效果图:
未设置mode:
mode:MODE_FIXED:
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<LinearLayout
android:id="@+id/tb"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
<com.ashokvarma.bottomnavigation.BottomNavigationBar
android:id="@+id/bottom_navigation_bar"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content"/>
</RelativeLayout>
主代码:
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.ashokvarma.bottomnavigation.BottomNavigationBar;
import com.ashokvarma.bottomnavigation.BottomNavigationItem;
/**
* BottomNavigationBar实现
*/
class MainActivity extends AppCompatActivity implements BottomNavigationBar.OnTabSelectedListener {
private BottomNavigationBar bottomNavigationBar;
int lastSelectedPosition = 0;
private String TAG = MainActivity.class.getSimpleName();
private LocationFragment mLocationFragment;
private FindFragment mFindFragment;
private FavoritesFragment mFavoritesFragment;
private BookFragment mBookFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNavigationBar = (BottomNavigationBar) findViewById(R.id.bottom_navigation_bar);
bottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);
bottomNavigationBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_RIPPLE);
bottomNavigationBar
.addItem(new BottomNavigationItem(R.mipmap.down_master_key, "位置").setActiveColor(Color.YELLOW))
.addItem(new BottomNavigationItem(R.mipmap.down_param, "发现").setActiveColor(Color.BLUE))
.addItem(new BottomNavigationItem(R.mipmap.login, "爱好").setActiveColor(Color.CYAN))
.addItem(new BottomNavigationItem(R.mipmap.merch_info, "图书").setActiveColor(Color.DKGRAY))
.setFirstSelectedPosition(lastSelectedPosition )
.initialise();
bottomNavigationBar.setTabSelectedListener(this);
setDefaultFragment();
}
/**
* 设置默认的
*/
private void setDefaultFragment() {
FragmentManager fm = getFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
mLocationFragment = LocationFragment.newInstance("位置");
transaction.replace(R.id.tb, mLocationFragment);
transaction.commit();
}
// 当第position个tab被选中时,调用此方法
// 这里可以完成对Fragment的切换
@Override
public void onTabSelected(int position) {
Log.d(TAG, "onTabSelected() called with: " + "position = [" + position + "]");
FragmentManager fm = this.getFragmentManager();
//开启事务
FragmentTransaction transaction = fm.beginTransaction();
switch (position) {
case 0:
if (mLocationFragment == null) {
mLocationFragment = LocationFragment.newInstance("位置");
}
transaction.replace(R.id.tb, mLocationFragment);
break;
case 1:
if (mFindFragment == null) {
mFindFragment = FindFragment.newInstance("发现");
}
transaction.replace(R.id.tb, mFindFragment);
break;
case 2:
if (mFavoritesFragment == null) {
mFavoritesFragment = FavoritesFragment.newInstance("爱好");
}
transaction.replace(R.id.tb, mFavoritesFragment);
break;
case 3:
if (mBookFragment == null) {
mBookFragment = BookFragment.newInstance("图书");
}
transaction.replace(R.id.tb, mBookFragment);
break;
default:
break;
}
// 事务提交
transaction.commit();
}
// 对未被选择的tab进行处理,其中pisition仍然是被选中的tab
@Override
public void onTabUnselected(int position) {
Log.d(TAG, "onTabUnselected() called with: " + "position = [" + position + "]");
}
// 当被选中的tab 再一次被点击时调用此方法
@Override
public void onTabReselected(int position) {
}
}
注意: bottomNavigationBar.setMode(BottomNavigationBar.MODE_FIXED);这里将mode设置成了fixed所以有了图二的效果
关于mode:
Java: setMode():MODE_DEFAULT,MODE_FIXED,MODE_SHIFTING
xml属性:bnbMode:mode_default,mode_fixed,mode_shifting
注意,mode需要在添加BottomNavigationItem之前进行设置,否则设置无效
关于style:
设置导航栏背景样式
java:
setBackgroundStyle():BACKGROUND_STYLE_DEFAULT,
BACKGROUND_STYLE_STATIC,
BACKGROUND_STYLE_RIPPLE
xml属性:
bnbBackgroundStyle:background_style_default,
background_style_static,
background_style_riple
效果就自行去慢慢试了。
给出一个Fragment代码:
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class LocationFragment extends Fragment {
public static LocationFragment newInstance(String param1) {
LocationFragment fragment = new LocationFragment();
Bundle args = new Bundle();
args.putString("agrs1", param1);
fragment.setArguments(args);
return fragment;
}
public LocationFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_location, container, false);
Bundle bundle = getArguments();
String agrs1 = bundle.getString("agrs1");
TextView tv = (TextView)view.findViewById(R.id.tv_location);
tv.setText(agrs1);
return view;
}
}
八 .DrawerLayout和NavigationView实现侧滑:
对于前面已经写了单独用DrawerLayout实现侧滑,现在有了NavigationView使我们更加方便的实现侧滑了
先看一下效果图:
NavigationView和以前的控件一样,只是多了两个特殊的属性
1.headerLayout:头部布局,图中绿色部分
2.menu:菜单,图中选项栏
使用方法:
镶嵌在DrawerLayout控件中
代码布局
activity_main:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
/>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<include layout="@layout/content_main" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
content_main就是一个HelloWolder,这里不再给出
看到NavigationView的headerLayout和menu属性,一个是layout,一个是menu,根据需求自定义
MainActivity:
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) this.findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
//menu属性item的监听事件
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
return true;
}
}
九、CoordinatorLayout与CollapsingToolbarLayout
CollapsingToolbarLayout作用是提供了一个可以折叠的Toolbar,它继承至FrameLayout,给它设置layout_scrollFlags,它可以控制包含在CollapsingToolbarLayout中的控件(如:ImageView、Toolbar)在响应layout_behavior事件时作出相应的scrollFlags滚动事件(移除屏幕或固定在屏幕顶端)。
效果图:
因为这个布局是根据滑动来突出效果的,所以这里我提供了一个RecyclerView
布局:
<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=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="256dp"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="#30469b"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/banner2"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7" />
<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.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
注意底部 LinearLayout我们加上了,表示在ToolBar下面显示
app:layout_behavior="@string/appbar_scrolling_view_behavior">
在CollapsingToolbarLayout中:
我们设置了layout_scrollFlags:关于它的值我这里再说一下:
scroll - 想滚动就必须设置这个。
enterAlways - 实现quick return效果, 当向下移动时,立即显示View(比如Toolbar)。
exitUntilCollapsed - 向上滚动时收缩View,但可以固定Toolbar一直在上面。
enterAlwaysCollapsed - 当你的View已经设置minHeight属性又使用此标志时,你的View只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
其中还设置了一些属性,简要说明一下:
contentScrim - 设置当完全CollapsingToolbarLayout折叠(收缩)后的背景颜色。
expandedTitleMarginStart - 设置扩张时候(还没有收缩时)title向左填充的距离。
在ImageView控件中:
我们设置了:
layout_collapseMode (折叠模式) - 有两个值:
pin - 设置为这个模式时,当CollapsingToolbarLayout完全收缩后,Toolbar还可以保留在屏幕上。
parallax - 设置为这个模式时,在内容滚动时,CollapsingToolbarLayout中的View(比如ImageView)也可以同时滚动,实现视差滚动效果,通常和layout_collapseParallaxMultiplier(设置视差因子)搭配使用。
layout_collapseParallaxMultiplier(视差因子) - 设置视差滚动因子,值为:0~1。
在Toolbar控件中:
我们设置了layout_collapseMode(折叠模式):为pin。
综上分析:当设置了layout_behavior的控件响应起了CollapsingToolbarLayout中的layout_scrollFlags事件时,ImageView会有视差效果的向上滚动移除屏幕,当开始折叠时CollapsingToolbarLayout的背景色(也就是Toolbar的背景色)就会变为我们设置好的背景色,Toolbar也一直会固定在最顶端。
主代码,其中RecylerView自行配置,比较简单:
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
//使用CollapsingToolbarLayout必须把title设置到CollapsingToolbarLayout上,设置到Toolbar上则不会显示
CollapsingToolbarLayout mCollapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar_layout);
mCollapsingToolbarLayout.setTitle("CollapsingToolbarLayout");
//通过CollapsingToolbarLayout修改字体颜色
mCollapsingToolbarLayout.setExpandedTitleColor(Color.WHITE);//设置还没收缩时状态下字体颜色
mCollapsingToolbarLayout.setCollapsedTitleTextColor(Color.GREEN);//设置收缩后Toolbar上字体的颜色