【Android】RecyclerView

來源:互聯網
上載者:User

標籤: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 等方法,所以,類似方法需要自己處理。

  1. 可以直接給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();    }}

    }

  2. 可以使用

    addOnItemTouchListener(RecyclerView.OnItemTouchListener listener)

    來進行全域處理。當然,缺點就是需要處理事件細節,比較繁瑣。

demo

demo

Android分享 Q群:315658668

【Android】RecyclerView

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.