本人所有文章首先發(fā)布于個(gè)人博客须喂,歡迎關(guān)注,地址:http://blog.isming.me
上次說(shuō)過(guò)使用主題,應(yīng)用Material Design的樣式到旦,同時(shí)卡片布局也是Material Design的重要組成部分柬祠,今天來(lái)寫(xiě)寫(xiě)淤毛。
引言
在程序中創(chuàng)建復(fù)雜的Material Design 樣式的 List和Card,可以使用RecyclerView和CardView組件,這兩個(gè)組件是在最新的support v7包(version 21)中提供的。因此需要引入依賴(lài)包:
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile 'com.android.support:cardview-v7:+'
compile 'com.android.support:recyclerview-v7:+'
}
創(chuàng)建List
RecylerView組件是一個(gè)更加高效靈活的ListView消别。這個(gè)組件時(shí)一個(gè)顯示大數(shù)據(jù)集的容器抛蚤,可以有效的滾動(dòng),保持顯示一定數(shù)量的視圖寻狂。使用RecyclerView組件霉颠,當(dāng)你有數(shù)據(jù)集,并且數(shù)據(jù)集的元素在運(yùn)行時(shí)根據(jù)用戶(hù)的操作或者網(wǎng)絡(luò)事件改變荆虱。
RecylerView類(lèi)簡(jiǎn)化大數(shù)據(jù)集的顯示和處理蒿偎,通過(guò)提供:
布局管理者控制元素定位朽们。
在通用的元素上操作上顯示默認(rèn)的動(dòng)畫(huà),比如移除和增加元素诉位。
使用RecyclerView組件骑脱,你需要指定一個(gè)Adapter和布局管理器,創(chuàng)建一個(gè)Adapter繼承RecyclerView.Adapter類(lèi)苍糠,具體的實(shí)現(xiàn)細(xì)節(jié)要根據(jù)數(shù)據(jù)集合視圖的類(lèi)型變化叁丧,具體信息,看下面的例子岳瞭。
一個(gè)布局管理器定位Item視圖在RecyclerView中拥娄,決定什么時(shí)候去回收它當(dāng)他不再可見(jiàn)時(shí)。當(dāng)重用(或者回收)一個(gè)視圖時(shí)瞳筏,布局管理器可能會(huì)請(qǐng)求適配器(Adapter)去替換子視圖中的內(nèi)容用不同的內(nèi)容稚瘾。通過(guò)這種方式回收重用視圖,可以減少view的創(chuàng)建和避免更多的findViewById()姚炕,從而提高性能摊欠。
RecyclerView提供了以下內(nèi)建的布局管理器:
LinearLayoutManager 顯示Item 在一個(gè)水平或者垂直的滾動(dòng)列表中。
GridLayoutManager 顯示Item 作為網(wǎng)格布局柱宦。
StaggeredGridLayoutManager 顯示Item在交錯(cuò)的網(wǎng)格布局些椒。
也可以自己通過(guò)繼承RecyclerView.LayoutManager類(lèi)創(chuàng)建自定義的布局管理器。

RecylerView組件
動(dòng)畫(huà):
RecyclerView默認(rèn)情況下就有動(dòng)畫(huà)掸刊,在刪除或者增加Ite的時(shí)候免糕。如果需要自定義動(dòng)畫(huà),繼承RecyclerView.ItemAnimator類(lèi)忧侧,并且使用RecyclerView.setItemAnimator()方法將定義的動(dòng)畫(huà)設(shè)置到我們的視圖中说墨。
下面開(kāi)始看例子:
1.首先在xml布局文件增加一個(gè)RecyclerView
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
2.然后在我們的Java代碼中使用,附加Adapter和數(shù)據(jù)就可以顯示了苍柏。
public class MyActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
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
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
}
...
}
3.Adapter提供訪問(wèn)數(shù)據(jù)集中的Item尼斧,創(chuàng)建視圖映射到數(shù)據(jù)上,并且替換布局的內(nèi)容數(shù)據(jù)用新的item试吁。下面的代碼顯示一個(gè)簡(jiǎn)單的實(shí)現(xiàn)棺棵,使用TextView顯示簡(jiǎn)單的String數(shù)組。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mTextView;
public ViewHolder(TextView v) {
super(v);
mTextView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
// set the view's size, margins, paddings and layout parameters
...
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mTextView.setText(mDataset[position]);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.length;
}
}
創(chuàng)建Card
CardView繼承FrameLayout類(lèi)熄捍,通過(guò)它可以顯示信息在卡片內(nèi)部烛恤,并且在不同的平臺(tái)上有統(tǒng)一的樣式。CardView組件可以有陰影和圓角余耽。
創(chuàng)建有陰影的Card,使用card_view:cardElevation屬性缚柏。CardView 使用真實(shí)的高度和動(dòng)態(tài)陰影在Android5.0(API 21)和更高版本,較早的版本則使用傳統(tǒng)的陰影碟贾。
使用這些屬性去定制CardView的外觀:
使用card_view:cardCornerRadius屬性設(shè)置圓角的半徑币喧,在布局文件中轨域。
使用CardView.setRadius方法設(shè)置圓角的半徑在java代碼中。
設(shè)置卡片的背景顏色杀餐,使用card_view:cardBackgroundColor屬性干发。
下面是一個(gè)在xml布局文件中包含一個(gè)CardView的示例:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
... >
<!-- A CardView that contains a TextView -->
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_gravity="center"
android:layout_width="200dp"
android:layout_height="200dp"
card_view:cardCornerRadius="4dp">
<TextView
android:id="@+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v7.widget.CardView>
</LinearLayout>

Card示例圖
亂彈
通過(guò)上面可以看到RecyclerView。跟我們經(jīng)常使用的ListView很像史翘,不過(guò)它的父類(lèi)并不是AbsListView,因此不能混著使用枉长。但是在很多地方可以替換ListView,通過(guò)ViewHolder,View重用,可以看到這是一個(gè)更加高效的視圖組件琼讽,推薦使用必峰。
CardView,本質(zhì)上就是一個(gè)比較符合Material Design的組件,使用Card布局钻蹬,效果更好吼蚁。很多人之前可能也使用一些CardUi,谷歌官方出了這個(gè),強(qiáng)烈推薦使用脉让。
上面RecyclerView和CardView,是分開(kāi)寫(xiě)的桂敛,但是我們可以用在一起的哦功炮,不要糊涂了呀溅潜。
參考資料:http://developer.android.com/training/material/lists-cards.html
原文地址:http://blog.isming.me/2014/10/21/creating-app-with-material-design-two-list/,轉(zhuǎn)載請(qǐng)注明出處薪伏。