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; } } }