【Android】RecyclerView

#RecyclerViewandroid

##RecyclerView簡明git

RecyclerView 在v7.21+包中,是一個用來展現大量數據的組件,或者說,就是ListView的改善版本(注:現階段的功能沒有ListView完善,所以想徹底取代ListView的話並不明智)。 相比ListView,RecyclerView的擴展性更好,所以也更適合與android新曾的組件配合使用,這樣使用起來更駕輕就熟。github

RecyclerView與ListView的原理差很少,本質上都是以適配器爲核心。只不過ListView緩存的是view,viewHolder附着在view上,而RecyclerView緩存的是viewHolder,view包含在viewHolder內。緩存

若是咱們將ListViewAdapter稍做修改,也能夠實現這種設計:ide

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使用this

####適配器 既然都是以適配器爲核心,所以,只須要寫好適配器就好了:.net

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),我的以爲的一個比較方便的地方就是,終於能夠方便的實現橫向列表</em>了!佈局管理的做用就是負責擺放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);
     }
    
     @Override
     public 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

相關文章
相關標籤/搜索