Android Material Design 详解(使用support v7兼容5.0以下系统)

来源:互联网 发布:传智播客168 erp 源码 编辑:程序博客网 时间:2024/06/05 03:22

Material Design是Google在2014年的I/O大会上推出的全新设计语言。Material Design是基于Android 5.0(API level 21)的,兼容5.0以下的设备时需要使用版本号v21.0.0以上的support v7包中的appcpmpat,不过遗憾的是support包只支持Material Design的部分特性。使用eclipse或Android Studio进行开发时,直接在Android SDK Manager中将Extras->Android Support Library升级至最新版即可。目前最新版本为:

[plain] view plain copy 在CODE上查看代码片派生到我的代码片
  1. com.android.support:appcompat-v7:21.0.3  

本文中示例程序使用minSdkVersion=14,即属于使用support包实现Material Design风格。

使用Material Design的步骤:

一、使用Material主题

1.创建一个Android应用,应用主题Theme.AppCompat(或其子主题,如Theme.AppCompat.Light.DarkActionBar)

2.自定义程序所使用的主题的某些属性,示例:

[html] view plain copy 在CODE上查看代码片派生到我的代码片
  1. <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">  
  2.         <!--ActionBar的颜色-->  
  3.         <item name="colorPrimary">@color/primary</item>  
  4.         <!-- 随主题而改变的颜色(如CheckBox的颜色)-->  
  5.         <item name="colorAccent">@color/accent</item>  
  6.         <!--状态栏的颜色 (使用support包时似乎无效。)-->  
  7.         <item name="colorPrimaryDark">@color/primary_dark</item>  
  8.   
  9.         <!--ActionBar的样式-->  
  10.         <item name="actionBarStyle">@style/AppTheme.ActionBarStyle</item>  
  11.     </style>  
  12.   
  13.     <style name="AppTheme.ActionBarStyle" parent="Widget.AppCompat.ActionBar.Solid">  
  14.         <item name="android:titleTextStyle">@style/AppTheme.ActionBar.TitleTextStyle</item>  
  15.     </style>  
  16.   
  17.     <style name="AppTheme.ActionBar.TitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionBar.Title">  
  18.         <!--ActionBar标题文字颜色-->  
  19.         <item name="android:textColor">@android:color/white</item>  
  20.     </style>  
3.所有需要使用ActionBar的Activity必须继承自ActionBarActivity,因为即使使用了类似Theme.AppCompat.Light.DarkActionBar这样的主题,系统也不会自动添加ActionBar.
效果图:生气

  

相对于普通的ActionBar的变化:

(1)右侧三个小点的样式变了。(这个无所谓。。。)

(2)点击右侧三个小点(更多)时,下拉菜单不是从ActionBar的下面开始展开,而是直接从ActionBar之上开始!也许的确有办法把它改成旧的样式,不过查阅官方文档之后发现,Google对此的解释是:菜单是一个临时展现给用户的组件,因此应该悬浮在上面。也就是说,新的设计规则推荐的就是这种默认的样式。

二、使用RecyclerView

RecyclerView是Google在support v7包中提供的一个全新的组件。该组件是一个增强版的ListView,新特性:

1.提高了性能;

2.adapter中自动进行item复用,也就是说,以前的这种繁琐的写法不需要了:

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. if (convertView == null) {  
  2.             convertView = LayoutInflater.from(context).inflate(R.layout.friends_item, parent, false);  
  3.             holder = new ViewHolder();  
  4.   
  5.             holder.nameTV = (TextView) convertView.findViewById(R.id.friends_item_name);  
  6.             holder.phoneTV = (TextView) convertView.findViewById(R.id.friends_item_phone);  
  7.             convertView.setTag(holder);  
  8.         } else {  
  9.             holder = (ViewHolder) convertView.getTag();  
  10.         }  

3.预置了item的添加,删除,移动,修改时的动画,当且改动画也可以自定义。

效果图:

    

示例代码:

(1)主页面,获取到RecyclerView,设置adapter即可。

[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);  
  2.  // use this setting to improve performance if you know that changes  
  3.  // in content do not change the layout size of the RecyclerView  
  4.   mRecyclerView.setHasFixedSize(true);  
  5.   
  6.  // use a linear layout manager  
  7. mRecyclerView.setLayoutManager(new LinearLayoutManager(this));  
  8. //data  
  9.  List<CityInfoBean> myDataset = new ArrayList<CityInfoBean>();  
  10.         for (int i = 0; i < 50; i++) {  
  11.             CityInfoBean city = new CityInfoBean();  
  12.             city.setCityName("Tianjin-" + i);  
  13.             city.setCityPhone("022-" + i);  
  14.             city.setLocation("Asia_" + i);  
  15.   
  16.             myDataset.add(city);  
  17.         }  
  18.   
  19.         RecyclerViewAdapter mAdapter = new RecyclerViewAdapter(this, myDataset);  
  20.         mRecyclerView.setAdapter(mAdapter);  
  21.   
  22. //RecyclerView doesn't has a 'OnItemClickListener' or 'OnItemLongClickListener' like ListView,  
  23.  // so you should add the callback in adapter   
(2)adapter,RecyclerViewAdapter.java:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
  1. public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {  
  2.     private Context context;  
  3.     private List<CityInfoBean> mDataset;  
  4.   
  5.     public RecyclerViewAdapter(Context context, List<CityInfoBean> myDataset) {  
  6.         this.context = context;  
  7.         mDataset = myDataset;  
  8.     }  
  9.   
  10.     // Create new views (invoked by the layout manager)  
  11.     @Override  
  12.     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  13.         View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_list_item, parent, false);  
  14.         // set the view's size, margins, paddings and layout parameters  
  15.   
  16.         final ViewHolder vh = new ViewHolder(v);  
  17.         v.setOnClickListener(new View.OnClickListener() {  
  18.             @Override  
  19.             public void onClick(View v) {  
  20.                 int position = vh.getPosition();  
  21.                 Toast.makeText(v.getContext(), "Item click. Position:" +  
  22.                         position, Toast.LENGTH_SHORT).show();  
  23.             }  
  24.         });  
  25.   
  26.         v.setOnLongClickListener(new View.OnLongClickListener() {  
  27.             @Override  
  28.             public boolean onLongClick(View v) {  
  29.                 int position = vh.getPosition();  
  30. //                Toast.makeText(v.getContext(), "Item long click. Position:" +  
  31. //                        position, Toast.LENGTH_SHORT).show();  
  32.   
  33.                 showDialog(position);  
  34.   
  35.                 return true;  
  36.             }  
  37.         });  
  38.   
  39.         return vh;  
  40.     }  
  41.   
  42.     // Replace the contents of a view (invoked by the layout manager)  
  43.     @Override  
  44.     public void onBindViewHolder(ViewHolder holder, int position) {  
  45.         holder.cityNameTV.setText(mDataset.get(position).getCityName());  
  46.         holder.phoneTV.setText(mDataset.get(position).getCityPhone());  
  47.         holder.addrTV.setText(mDataset.get(position).getLocation());  
  48.     }  
  49.   
  50.     @Override  
  51.     public int getItemCount() {  
  52.         return mDataset.size();  
  53.     }  
  54.   
  55.     private void showDialog(final int position) {  
  56.         AlertDialog.Builder builder = new AlertDialog.Builder(context);  
  57.         builder.setTitle("Choose operation");  
  58.   
  59.         String[] dialogItems = new String[]{  
  60.                 context.getString(R.string.delete_one_item),  
  61.                 context.getString(R.string.add_one_item),  
  62.                 context.getString(R.string.move_one_item),  
  63.                 context.getString(R.string.change_one_item),  
  64.                 context.getString(R.string.add_many_items),  
  65.         };  
  66.         builder.setItems(dialogItems, new DialogInterface.OnClickListener() {  
  67.             @Override  
  68.             public void onClick(DialogInterface dialog, int which) {  
  69.                 switch (which) {  
  70.                     case 0:  
  71.                         //delete this item  
  72.                         mDataset.remove(position);  
  73.                         notifyItemRemoved(position);  
  74.                         break;  
  75.                     case 1:  
  76.                         //add one item  
  77.                         mDataset.add(position, new CityInfoBean("New City""010""Asia"));  
  78.                         notifyItemInserted(position);  
  79.                         break;  
  80.                     case 2:  
  81.                         //TODO remember to change the data set...  
  82.                         //move one item to another position  
  83.                         notifyItemMoved(position, position + 2);  
  84.                         //May cause IndexOutOfBoundsException. This is just a demo!  
  85.                         break;  
  86.                     case 3:  
  87.                         //change one item  
  88.                         mDataset.get(position).setCityName("City name changed");  
  89.                         notifyItemChanged(position);  
  90.                         break;  
  91.                     case 4:  
  92.                         //add many items  
  93.                         List<CityInfoBean> insertList = new ArrayList<CityInfoBean>();  
  94.                         insertList.add(new CityInfoBean("New City 01""010""Asia"));  
  95.                         insertList.add(new CityInfoBean("New City 02""020""America"));  
  96.   
  97.                         mDataset.addAll(position, insertList);  
  98.                         notifyItemRangeInserted(position, insertList.size());  
  99.                         break;  
  100.                     default:  
  101.                         break;  
  102.                 }  
  103.             }  
  104.         });  
  105.   
  106.         builder.create().show();  
  107.     }  
  108.   
  109.     public static class ViewHolder extends RecyclerView.ViewHolder {  
  110.         public TextView cityNameTV, phoneTV, addrTV;  
  111.   
  112.         public ViewHolder(View v) {  
  113.             super(v);  
  114.   
  115.             cityNameTV = (TextView) v.findViewById(R.id.city_name);  
  116.             phoneTV = (TextView) v.findViewById(R.id.city_phone);  
  117.             addrTV = (TextView) v.findViewById(R.id.city_addr);  
  118.         }  
  119.     }  
  120. }  
(3)主页面布局文件:

recycler_layout.xml:

[html] view plain copy 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent">  
  6.   
  7.     <android.support.v7.widget.RecyclerView  
  8.         android:id="@+id/my_recycler_view"  
  9.         android:scrollbars="vertical"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent" />  
  12.   
  13. </LinearLayout>  

二、使用CardView

CardView是Google在support v7包中提供了另一个全新组件,可以很方便的实现“卡片式布局”(具有投影/圆角 的立体效果)。CardView继承自FrameLayout,因此如果内部需要互不重叠的放置多个组件时,可能需要再嵌套一个LinearLayout或RelativeLayout等。

效果图:


布局文件:

[html] view plain copy 在CODE上查看代码片派生到我的代码片
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="wrap_content"  
  4.     xmlns:card_view="http://schemas.android.com/apk/res-auto">  
  5.   
  6.     <android.support.v7.widget.CardView  
  7.         android:id="@+id/card_view"  
  8.         android:layout_gravity="center"  
  9.         android:layout_width="match_parent"  
  10.         android:layout_height="200dp"  
  11.         android:layout_margin="6dp"  
  12.         card_view:cardCornerRadius="4dp"  
  13.         card_view:cardBackgroundColor="@color/card_bg"  
  14.         card_view:cardElevation="4dp">  
  15.   
  16.         <LinearLayout  
  17.             android:layout_width="match_parent"  
  18.             android:layout_height="match_parent"  
  19.             android:layout_margin="6dp"  
  20.             android:orientation="vertical">  
  21.   
  22.             <ImageView  
  23.                 android:layout_width="wrap_content"  
  24.                 android:layout_height="wrap_content"  
  25.                 android:contentDescription="@null"  
  26.                 android:src="@drawable/ic_launcher" />  
  27.   
  28.             <TextView  
  29.                 android:id="@+id/info_text"  
  30.                 android:layout_width="match_parent"  
  31.                 android:layout_height="match_parent"  
  32.                 android:textSize="18sp"  
  33.                 android:text="@string/example_text" />  
  34.   
  35.         </LinearLayout>  
  36.   
  37.     </android.support.v7.widget.CardView>  
  38.   
  39. </LinearLayout>  
属性解释:

cardCornerRadius:圆角大小;

cardElevation:投影的深度;

cardBackgroundColor:卡片的背景色。

============================================================

源码下载(免积分哦):http://download.csdn.net/detail/books1958/8269227



转自:http://blog.csdn.net/books1958/article/details/41956093

0 0
原创粉丝点击