Android应用的Material设计的布局兼容性的一些要点总结
DefineAlternativeStyles 定义替代样式
让你的app,使用MaterialDesign的主题运行在支持它的设备上,并在早期版本的设备上可以运行较早的主题:
1.在res/values/styles.xml定义一个主题继承较早的主题
2.在res/values-v21/styles.xml定义一个相同名字的继承自Material主题的主题
3.在manifest中应用定义的主题
注:如果你的app使用了Material主题,而不提供较早的主题,那么将不能运行在早期版本的设备上
ProvideAlternativeLayouts 提供替代布局
如果你设计的layout不引用任何的5.0中的xml属性,那么可以运行在早期版本的Android设备上。否则,你可提供一个替代布局。
替代布局建立在res/layout-v21/
为了避免重复代码,可以在res/values/ 定义你的styles,新风格的在res/values-21/中定义,并使用style的继承,在res/values中定义一个baseStyle,在res/values-21中继承它。
UsetheSupportLibrary 使用支持库
v7supportlibrary包括以下的一些特性:
- 在应用了一个Theme.AppCompat主题后,系统的一些组件就有了MaterialDesign的风格
- 在Theme.AppCompat主题中,有调色主题
- RecyclerView组件显示数据集
- CardView组件创建卡片
- 从图像中取色
Systemwidgets 系统组件
Theme.AppCompat主题提供的MaterialDesign风格的组件有:
- EditText
- Spinner
- CheckBox
- Radiobutton
- SwitchCompat
- CheckedTextView
ColorPalette
使用v7支持库,获得MaterialDesign风格定义颜色板,应用一个Theme.AppCompat主题:
<!--extendoneoftheTheme.AppCompatthemes--> <stylename="Theme.MyTheme"parent="Theme.AppCompat.Light"> <!--customizethecolorpalette--> <itemname="colorPrimary">@color/material_blue_500</item> <itemname="colorPrimaryDark">@color/material_blue_700</item> <itemname="colorAccent">@color/material_green_A200</item> </style>
ListsandCards
使用v7支持库后,在早期的Android版本上也可运行。
Dependencies
gradle依赖:
dependencies{
compile'com.android.support:appcompat-v7:21.0.+'
compile'com.android.support:cardview-v7:21.0.+'
compile'com.android.support:recyclerview-v7:21.0.+'
}
ChecktheSystemVersion 检查系统版本
以下特性只能在Android5.0(API级别21)及以上:
- Activitytransitions 活动转换
- Touchfeedback 触觉反馈
- Revealanimations 显示动画
- Path-basedanimations 基于路径动画
- Vectordrawables 矢量图片
- Drawabletinting 图片染色
检查代码:
//Checkifwe'rerunningonAndroid5.0orhigher
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){
//CallsomematerialdesignAPIshere
}else{
//Implementthisfeaturewithoutmaterialdesign
}
注:要让app支持5.0,需要在manifest中Android:targetSdkVersion=21。
PS:RecyclerView
附RecyclerView的例子:
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.support.v7.widget.GridLayoutManager;
importandroid.support.v7.widget.RecyclerView;
importandroid.support.v7.widget.RecyclerView.LayoutParams;
importandroid.view.LayoutInflater;
importandroid.view.ViewGroup;
importandroid.widget.TextView;
publicclassRecyclerViewActivityextendsActivity{
/*
*recyclerview提供这些内置的布局管理器:
*linearlayoutmanager显示垂直滚动列表或水平的项目。
*gridlayoutmanager显示在一个网格项目。
*staggeredgridlayoutmanager显示在交错网格项目。
*自定义的布局管理器,需要继承recyclerview.layoutmanager类。
*
*add/removeitems时的动画是默认启用的。
*自定义这些动画需要继承RecyclerView.ItemAnimator,并实现RecyclerView.setItemAnimator()
*/
privateRecyclerViewmRecyclerView;
privateRecyclerView.AdaptermAdapter;
privateRecyclerView.LayoutManagermLayoutManager;
privateString[]myDataset;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_view);
mRecyclerView=(RecyclerView)findViewById(R.id.my_recycler_view);
//usethissettingtoimproveperformanceifyouknowthatchanges
//incontentdonotchangethelayoutsizeoftheRecyclerView
mRecyclerView.setHasFixedSize(true);
//usealinearlayoutmanager
//mLayoutManager=newLinearLayoutManager(this);
//mLayoutManager=newGridLayoutManager(this,3,GridLayoutManager.VERTICAL,true);
//true表示,将layout内容反转
mLayoutManager=newGridLayoutManager(this,3,GridLayoutManager.VERTICAL,false);
//HORIZONTAL横向滚动显示内容VERTICAL纵向
//mLayoutManager=newGridLayoutManager(this,3,GridLayoutManager.HORIZONTAL,false);
//方向也是指示滚动方向,例子中横向开头的数据交错了一点,纵向的无交错
//mLayoutManager=newStaggeredGridLayoutManager(3,StaggeredGridLayoutManager.HORIZONTAL);
//mLayoutManager=newStaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
//mRecyclerView.setLayoutManager(newMyLayoutMnager());//数据不显示,可能还需要重写什么东西。。
//specifyanadapter(seealsonextexample)
setDatas();
mAdapter=newMyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
}
privatevoidsetDatas(){
intlen=200;
myDataset=newString[len];
for(inti=0;i<len;i++){
switch(i%3){
case0:
myDataset[i]="中国"+i;
break;
case1:
myDataset[i]="美国"+i;
break;
case2:
myDataset[i]="澳大利亚"+i;
break;
}
}
}
classMyLayoutMnagerextendsRecyclerView.LayoutManager{
@Override
publicLayoutParamsgenerateDefaultLayoutParams(){
LayoutParamsparams=newLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
params.topMargin=5;
returnparams;
}
}
classMyAdapterextendsRecyclerView.Adapter<ViewHolder>{
privateString[]mDataset;
//Provideareferencetotheviewsforeachdataitem
//Complexdataitemsmayneedmorethanoneviewperitem,and
//youprovideaccesstoalltheviewsforadataiteminaviewholder
//Provideasuitableconstructor(dependsonthekindofdataset)
publicMyAdapter(String[]myDataset){
mDataset=myDataset;
}
//Createnewviews(invokedbythelayoutmanager)
@Override
publicViewHolderonCreateViewHolder(ViewGroupparent,intviewType){
//createanewview
TextViewtv=(TextView)LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view,parent,false);
//settheview'ssize,margins,paddingsandlayoutparameters
//...
ViewHoldervh=newViewHolder(tv);//构建一个ViewHolder
returnvh;
}
//Replacethecontentsofaview(invokedbythelayoutmanager)
@Override
publicvoidonBindViewHolder(ViewHolderholder,intposition){
//-getelementfromyourdatasetatthisposition
//-replacethecontentsoftheviewwiththatelement
holder.mTextView.setText(mDataset[position]);
}
//Returnthesizeofyourdataset(invokedbythelayoutmanager)
@Override
publicintgetItemCount(){
returnmDataset.length;
}
}
staticclassViewHolderextendsRecyclerView.ViewHolder{
//eachdataitemisjustastringinthiscase
publicTextViewmTextView;
publicViewHolder(TextViewv){
super(v);
mTextView=v;
}
}
}
