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

Android Material Design 详解(使用support v7兼容5.0以下系统)
2014-12-18       5  个评论    来源:books1958的专栏  
收藏     我要投稿

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升级至最新版即可。目前最新版本为:

 

?
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.自定义程序所使用的主题的某些属性,示例:

 

?
1
2
3
4
5
6
7
8
9
10
<style name= "AppTheme" parent= "Theme.AppCompat.Light.DarkActionBar" type= "text/css" ><!--ActionBar的颜色-->
         <item name=colorPrimary> @color /primary</item>
         <!-- 随主题而改变的颜色(如CheckBox的颜色)-->
         <item name=colorAccent> @color /accent</item>
         <!--状态栏的颜色 (使用support包时似乎无效。)-->
         <item name=colorPrimaryDark> @color /primary_dark</item>
 
         <!--ActionBar的样式-->
         <item name=actionBarStyle> @style /AppTheme.ActionBarStyle</item></style><style name= "AppTheme.ActionBarStyle" parent= "Widget.AppCompat.ActionBar.Solid" type= "text/css" ><item name=android:titleTextStyle> @style /AppTheme.ActionBar.TitleTextStyle</item></style><style name= "AppTheme.ActionBar.TitleTextStyle" parent= "@style/TextAppearance.AppCompat.Widget.ActionBar.Title" type= "text/css" ><!--ActionBar标题文字颜色-->
         <item name=android:textColor> @android :color/white</item></style>
3.所有需要使用ActionBar的Activity必须继承自ActionBarActivity,因为即使使用了类似Theme.AppCompat.Light.DarkActionBar这样的主题,系统也不会自动添加ActionBar.
效果图: 生气

 

height=400 height=400

相对于普通的ActionBar的变化:

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

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

二、使用RecyclerView

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

1.提高了性能;

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

 

?
1
2
3
4
5
6
7
8
9
10
if (convertView == null ) {
             convertView = LayoutInflater.from(context).inflate(R.layout.friends_item, parent, false );
             holder = new ViewHolder();
 
             holder.nameTV = (TextView) convertView.findViewById(R.id.friends_item_name);
             holder.phoneTV = (TextView) convertView.findViewById(R.id.friends_item_phone);
             convertView.setTag(holder);
         } else {
             holder = (ViewHolder) convertView.getTag();
         }

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

效果图:

height=400 height=400

示例代码:

 

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

 

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

 

recycler_layout.xml:

 

?
1
2
3
4
5
6
<!--?xml version= 1.0 encoding=utf- 8 ?-->
<linearlayout android:layout_height= "match_parent" android:layout_width= "match_parent" android:orientation= "vertical" xmlns:android= "http://schemas.android.com/apk/res/android" >
 
     
 
</android.support.v7.widget.recyclerview></linearlayout>

二、使用CardView

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

效果图:

height=400

布局文件:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<linearlayout android:layout_height= "wrap_content" android:layout_width= "match_parent" xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:card_view= "http://schemas.android.com/apk/res-auto" >
 
     
 
         <linearlayout android:layout_height= "match_parent" android:layout_margin= "6dp" android:layout_width= "match_parent" android:orientation= "vertical" >
 
             <imageview android:contentdescription= "@null" android:layout_height= "wrap_content" android:layout_width= "wrap_content" android:src= "@drawable/ic_launcher" >
 
             <textview android:id= "@+id/info_text" android:layout_height= "match_parent" android:layout_width= "match_parent" android:text= "@string/example_text" android:textsize= "18sp" >
 
         </textview></imageview></linearlayout>
 
     </android.support.v7.widget.cardview>
 
</linearlayout>
属性解释:

 

cardCornerRadius:圆角大小;

cardElevation:投影的深度;

cardBackgroundColor:卡片的背景色。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值