題外話
前些天在使用Materal Design風(fēng)格的控件時,用到了CoordinatorLayout組件+Toorbar+滑動組件時搭配使用實現(xiàn)滑動時Toorbar上隱和顯示功能時,發(fā)現(xiàn)滑動組件使用ListView時并不能實現(xiàn)其功能隘马,然而使用RecyclerView 便可以免钻,發(fā)現(xiàn)感覺能使用ListView的地方RecyclerView也能達到目的盏袄,反而有些ListView并不能實現(xiàn)一些功能芳绩,感覺ListView過時了。好了廢話不多說柴淘,來講講我們要使用的RecyclerView:
RecyclerView簡單介紹
RecyclerView 是Google在Android 5.0之后加的控件迫淹,是僅僅維護少量的View并且可以展示大量的數(shù)據(jù)集。它更像一個容器为严,它比 ListView更加強大 敛熬,靈活,但是實現(xiàn)跟困難了點第股,Android就推薦使用ViewHolder來減少findViewById()的使用以提高效率应民。對于RecyclerView上的ViewHolder,則需要強制使用夕吻,說它靈活诲锹,RecyclerView不僅僅像ListView那樣只有一種item排列方式,有它自己的布局管理器RecyclerView.LayoutManager涉馅,可以設(shè)置三種方式归园,等下會說到。好多功能都要自己實現(xiàn)比如item點擊事件稚矿。RecyclerView有如下幾個重要部分:
- RecyclerView.adapter
它和LIstView的adapter一樣都是實現(xiàn)適配庸诱。很多方法都放在adapter類里來實現(xiàn)。 - RecyclerView.VIewHolder
持有所有的用于綁定數(shù)據(jù)或者需要操作的View,實現(xiàn)item里面每個子控件的findViewById() - RecyclerView.LayoutManager
布局管理器晤揣,負責(zé)擺放視圖等相關(guān)操作桥爽。有如下三種布局方式:
LinearLayoutManager: 以垂直或水平滾動列表方式顯示項目。
GridLayoutManager: 在網(wǎng)格中顯示項目昧识。
StaggeredGridLayoutManager: 在分散對齊網(wǎng)格中顯示項目 - ItemDecoration
RecyclerView 沒有像ListView那樣的分割線钠四,只有通過這個類實現(xiàn);
RecyclerView簡單使用
- 添加依賴
dependencies {
compile 'com.android.support:recyclerview-v7:23.4.0'
}
- main_activity布局中加入如下代碼
<android.support.v7.widget.RecyclerView
android:id="@+id/recycleview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
- 每個item的布局文件
這里就只寫了一個文本跪楞,需要什么樣的item可以自己定義
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:background="@drawable/recyclerview_selector"
android:clickable="true"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="60dp"
android:textSize="20dp"
android:gravity="center"/>
</LinearLayout>
-
其實最重要的還是自定義RecyclerViewadapter這個類必須實現(xiàn)下面幾個:
1.自定義ViewHolder
包含item的所有界面元素缀去。2.onCreateViewHolder(ViewGroup parent, int viewType)
這個方法用來創(chuàng)建View,被LayoutManager所用,說簡單點就是獲取RecyclerView的每個Item甸祭,但最后返回的不是view而是自定義ViewHolder的對象朵耕。
3.onBindViewHolder(final ViewHolder holder, int position)
這個方法用來綁定數(shù)據(jù)
4.getItemCount()
返回item的個數(shù)
具體代碼如下:
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder> {
private List<String> lists=null;
private Context context;
public RecycleViewAdapter(Context context, List<String> lists) {
this.context = context;
this.lists = lists;
}
//創(chuàng)建View,被LayoutManager所用
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recyclerviewitem_layout,parent,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
//數(shù)據(jù)的綁定
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.textView.setText(lists.get(position));
}
@Override
public int getItemCount() {
return lists.size();
}
//自定義ViewHolder,包含item的所有界面元素
public static class ViewHolder extends RecyclerView.ViewHolder {
public final TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textview);
}
}
}
- 在MainActivity中實現(xiàn)相關(guān)代碼
/**
* Created by xiaozhuang on 2017/1/2015:09.
* E_mail:1058081812@qq.com
*/
public class RecycleViewActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private List<String> lists;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycleview_layout);
//模擬一些數(shù)據(jù)加載
lists = new ArrayList<>();
for (int i = 0; i < 50; i++) {
lists.add(i + "item");
}
recyclerView = (RecyclerView) findViewById(R.id.recycleview);
//這里使用線性布局像listview那樣展示列表,第二個參數(shù)可以改為 HORIZONTAL實現(xiàn)水平展示
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
//使用網(wǎng)格布局展示
// recyclerView.setLayoutManager(new GridLayoutManager(this, 5));
recyclerView.setLayoutManager(linearLayoutManager);
final RecycleViewAdapter adapter = new RecycleViewAdapter(this, lists);
//設(shè)置分割線使用的divider
recyclerView.addItemDecoration(new android.support.v7.widget.DividerItemDecoration(this, android.support.v7.widget.DividerItemDecoration.VERTICAL));
recyclerView.setAdapter(adapter);
}
}
注釋:這里使用的自帶的分割線,你也可以自定義
查看DividerItemDecoration類淋叶,可以看到使用的分割線是系統(tǒng)的android:listDivider
所以你只要在style.xml中加入一個
<item name="android:listDivider">@drawable/divider_bg</item>
后面的divider_bg.xml可以自己定義
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- gradient定義漸變色填充-->
<gradient
android:startColor="#FFFFFF"
android:centerColor="#FFFFFF"
android:endColor="#FFFFFF"
android:type="linear" />
<size android:height="2dp"/>
</shape>
-效果展示
采用如下布局:
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
recyclerView.addItemDecoration(new android.support.v7.widget.DividerItemDecoration(this,
DividerItemDecoration.HORIZONTAL));
效果如下:
- 另外你會發(fā)現(xiàn)RecyclerView并不像ListView一樣可以直接設(shè)置item點擊事件
需要自己在adapter類中定義接口并且暴露出方法設(shè)置點擊事件具體如下:
/**
* Created by xiaozhuang on 2017/1/2015:18.
* E_mail:1058081812@qq.com
*/
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder> {
private List<String> lists=null;
private Context context;
public RecycleViewAdapter(Context context, List<String> lists) {
this.context = context;
this.lists = lists;
}
//創(chuàng)建View,被LayoutManager所用
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recyclerviewitem_layout,parent,false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
//item點擊的監(jiān)聽接口
public interface OnItemClikListener{
void onItemClik(View view,int position);
void onItemLongClik(View view,int position);
}
private OnItemClikListener mOnItemClikListener;
//對外設(shè)置item點擊暴露的方法
public void setItemClikListener(OnItemClikListener mOnItemClikListener ){
this.mOnItemClikListener=mOnItemClikListener;
}
//數(shù)據(jù)的綁定
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.textView.setText(lists.get(position));
//對外調(diào)用了方法
if(mOnItemClikListener!=null){
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos=holder.getLayoutPosition();
mOnItemClikListener.onItemClik(holder.itemView,pos);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int pos=holder.getLayoutPosition();
mOnItemClikListener.onItemLongClik(holder.itemView,pos);
return false;
}
});
}
}
@Override
public int getItemCount() {
return lists.size();
}
//自定義ViewHolder,包含item的所有界面元素
public static class ViewHolder extends RecyclerView.ViewHolder {
public final TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView.findViewById(R.id.textview);
}
}
}
然后在主文件中加入如下代碼就可以了:
adapter.setItemClikListener(new RecycleViewAdapter.OnItemClikListener() {
@Override
public void onItemClik(View view, int position) {
Toast.makeText(RecycleViewActivity.this, "點擊了" + position, Toast.LENGTH_LONG).show();
}
@Override
public void onItemLongClik(View view, int position) {
Toast.makeText(RecycleViewActivity.this, "長按點擊了" + position, Toast.LENGTH_LONG).show();
}
});
最后那個增加阎曹,刪除動畫我沒有用到這里就沒寫;只寫了簡單的用法
如果嫌設(shè)置分割線麻煩就可以使用CardView+RecyclerView就行了這里給張截圖