標籤:android http io ar os 使用 sp java for
RecyclerView RecyclerView簡明
RecyclerView 在v7.21+包中,是一個用來展示大量資料的組件,或者說,就是ListView的改善版本(註:現階段的功能沒有ListView完善,因此想完全取代ListView的話並不明智)。
相比ListView,RecyclerView的擴充性更好,因此也更適合與android新曾的組件配合使用,這樣使用起來更得心應手。
RecyclerView與ListView的原理差不多,本質上都是以適配器為核心。只不過ListView緩衝的是view,viewHolder附著在view上,而RecyclerView緩衝的是viewHolder,view包含在viewHolder內。
如果我們將ListViewAdapter稍作修改,也可以實現這種設計:
abstract class LvAdapter<VH extends LvAdapter.ViewHolder> extends BaseAdapter { public class ViewHolder { private View view; public ViewHolder(View view) { this.view = view; } public View getView() { return view; } } @Override public int getCount() { return 0; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { VH vh = getViewHolder(); onBindViewHolder(vh, position); return vh.getView(); } public abstract VH getViewHolder(); public abstract void onBindViewHolder(VH holder, int position);}
這樣有點不直觀,所以更進一步,ListView的Adapter可以更抽象,將資料繫結方法交給viewHolder,這樣adapter的工作就更單純一點.
一個方便的ListViewAdapter可以參考base-adapter-helper
RecyclerView使用 適配器
既然都是以適配器為核心,因此,只需要寫好適配器就行了:
class RvViewHolder extends RecyclerView.ViewHolder { public TextView tv; public RvViewHolder(View itemView) { super(itemView); tv = (TextView) itemView.findViewById(R.id.tv); }}class RvAdapter extends RecyclerView.Adapter<RvViewHolder> { Context context; String[] items; public RvAdapter(Context context, String[] items) { this.context = context; this.items = items; } @Override public RvViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.apt_v7_recycler_view, parent, false); return new RvViewHolder(view); } @Override public void onBindViewHolder(RvViewHolder holder, int position) { holder.tv.setText(items[position]); } @Override public int getItemCount() { return items.length; }}rv.setAdapter(new RvAdapter(this, new String[]{ "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D"}));LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);linearLayoutManager.setOrientation(LinearLayout.VERTICAL);rv.setLayoutManager(linearLayoutManager); 布局管理器 與 橫向列表
RecyclerView的另一個特點就是布局管理器(LayoutManager),個人覺得的一個比較方便的地方就是,終於可以方便的實現橫向列表了!布局管理的作用就是負責擺放view以及回收view。
類似的
int findFirstVisibleItemPosition();int findLastVisibleItemPosition();
方法也在布局管理器中
設定item動畫
rv.setItemAnimator(ItemAnimator);
分割線
由於RecyclerView的布局不固定,因此沒有像ListView那樣直接設定divider的方式,這些可能需要自己實現。一個簡單粗魯的縱向列表分割線如下:
rv.addItemDecoration(new RecyclerView.ItemDecoration() { Paint paint = new Paint(); @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); for (int i = 0, size = parent.getChildCount(); i < size; i++) { View child = parent.getChildAt(i); c.drawLine(child.getLeft(), child.getBottom(), child.getRight(), child.getBottom(), paint); } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); }});
還可以參考:DividerItemDecoration
綁定事件
RecyclerView 沒有 ListView 的 OnItemClick 等方法,所以,類似方法需要自己處理。
可以直接給itemView或者其子view綁定事件,綁定可以在viewHolder中進行事件綁定,也可以在adapter中進行。
不過viewHolder中無法直觀擷取到原始的Item資料,需要進一步的處理(比如給itemView設定tag)才能實現擷取未經處理資料的目的,所以怎麼使用需要自己權衡。
class RvViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView tv;public RvViewHolder(View itemView) { super(itemView); tv = (TextView) itemView.findViewById(R.id.tv); itemView.setTag(this); itemView.setOnClickListener(this);}@Overridepublic void onClick(View v) { int vId = v.getId(); if (vId == R.id.tv) { Toast.makeText(itemView.getContext(), getPosition() + "", Toast.LENGTH_SHORT).show(); }} }
可以使用
addOnItemTouchListener(RecyclerView.OnItemTouchListener listener)
來進行全域處理。當然,缺點就是需要處理事件細節,比較繁瑣。
demo
demo
Android分享 Q群:315658668
【Android】RecyclerView