Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> RecyclerView.Adapter的優化與封裝

RecyclerView.Adapter的優化與封裝

編輯:關於Android編程

說實在的,敲代碼和看書相比較,我還是看書或是看博文看得多,到現在好久都沒練練手了,然後在簡書上面看了別人對adapter的封裝和優化,嘿,還真的挺不錯的,adapter真的簡潔了不少,看完了思路,原來這麼簡單的啊,好了,開始表演真正的技術了。

項目結構圖

這裡寫圖片描述

主要是對BaseRecycleAdapter和BaseViewHolder進行封裝。

好了,開始講課了^_^。

BaseRecycleAdapter.class

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;
import css.lontano.coordinatorlayouttest.javabean.BaseBean;

/**
 * Created by wangqi on 2016/7/16.
 */
public abstract class BaseRecycleAdapter extends RecyclerView.Adapter {
    private int layoutId;
    private List data;
    private Context context;
    private OnItemClickListner onItemClickListner;//單擊事件
    private OnItemLongClickListner onItemLongClickListner;//長按單擊事件
    private boolean clickFlag = true;//單擊事件和長單擊事件的屏蔽標識

    /**
     *
     * @param context //上下文
     * @param layoutId  //布局id
     * @param data  //數據源
     */
    public BaseRecycleAdapter(Context context, int layoutId, List data) {
        this.layoutId = layoutId;
        this.data = data;
        this.context = context;
    }

    @Override
    public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(context).inflate(layoutId, parent, false);
        final BaseViewHolder holder = new BaseViewHolder(v, context);
        //單擊事件回調
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (clickFlag) {
                    onItemClickListner.onItemClickListner(v,holder.getLayoutPosition());
                }
                clickFlag = true;
            }
        });
        //單擊長按事件回調
        v.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                onItemLongClickListner.onItemLongClickListner(v,holder.getLayoutPosition());
                clickFlag = false;
                return false;
            }
        });
        return holder;
    }

    @Override
    public void onBindViewHolder(BaseViewHolder holder, int position) {
        convert(holder, data.get(position));
    }

    protected abstract  void convert(BaseViewHolder holder, T bean);

    @Override
    public int getItemCount() {
        return data.size();
    }

    public void setOnItemClickListner(OnItemClickListner onItemClickListner) {
        this.onItemClickListner = onItemClickListner;
    }

    public void setOnItemLongClickListner(OnItemLongClickListner onItemLongClickListner) {
        this.onItemLongClickListner = onItemLongClickListner;
    }

    public interface OnItemClickListner {
        void onItemClickListner(View v,int position);
    }

    public interface OnItemLongClickListner {
        void onItemLongClickListner(View v,int position);
    }
}

BaseRecycleAdapter類裡面其實沒什麼,就和普通的adapter沒什麼區別,只是將數據的設置用抽象方法去表示,然後讓繼承類去實現結果操作。
看到上面的代碼,大家應該看到了兩個重點:
一、單擊事件的回調:
RecyclerView默認是沒有像ListView的onItemClick方法的,我們必須得自己去實現,我是直接給引用 的布局設置點擊事件和長點擊事件,這個點擊事件最好是設置在onCreateViewHolder方法中,因為RecyclerAdapter初始化只調用一次,而有些人習慣設置在onBindViewHolder方法中,這樣每次更新View都要去設置一遍監聽事件,是沒有必要的操作。大家看到我在兩個事件的回調裡面設置了一個clickFlag單擊標記,大家知道是為了避免什麼嗎?操作實驗過的同學應該就會知道了,假如不設置這些標志,在進行長點擊操作松開手指會發現,他還會再觸發一次短單擊事件,所以為了避免長點擊操作帶來的兩次回調效果,先設置clickFlag為true,此時可以短點擊,當長單擊操作開始時,我們設置clickFlag為false,這是長單擊回調結束,進入了短單擊,發現此時clickFlag是為false的,所以就不回調短單擊的事件,最後又重新設置回可短單擊效果,這部分要是不明白的可以給我留言。
二、數據傳遞用泛型
①List< ? extends BaseBean> data
② protected abstract void convert(BaseViewHolder holder, T bean);
這兩個部分都是泛型的巧用,以前不會玩這些,java打的不牢,後來看鴻洋的博客,對於封裝這塊用的特別多,忽然發現泛型的重要性,然後重回宿捨,拿起李剛的《瘋狂java講義》狂看,看完之後,原來是這樣的啊,? extends BaseBean表現為集合數據裡面存儲的類型是BaseBean或是BaseBean的子類,也就是向下,如果是? super BaseBean 則存儲的數據類型為BaseBean或BaseBean的父類,也就是向上,大概好像是這麼理解的,如有錯誤,大家指出來喔,
我這邊存儲的數據類型Model,bean都必須要繼承BaseBean這個父類,因為泛型傳遞,所以我就這麼做了,要是大家有什麼好的方法的話,也可以告訴告訴我,就怕沒有知識汲取。

BaseBean.class 和Person.class

這裡寫圖片描述

BaseViewHolder.class

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

/**
 * Created by Administrator on 2016/7/16.
 */
public class BaseViewHolder extends RecyclerView.ViewHolder {
    View convertView;
    Context context;

    public BaseViewHolder(View itemView, Context context) {
        super(itemView);
        this.convertView = itemView;
        this.context = context;
    }

    public void setText(int id, String text) {
        TextView tx = (TextView) convertView.findViewById(id);
        tx.setText(text);
    }

    public void setImageResource(int id, int resouceId) {
        ImageView img= (ImageView) convertView.findViewById(id);
        img.setImageResource(resouceId);
    }

}

BaseViewHolder這個類呢一般都是拿來優化RecycleView的,然後拿到這個holder來設置數據,RecycleAdapter的onCreateViewHolder方法將填充的item布局返回給了BaseViewHolder,然後將這個view設置為全局,下面的那些setText或是setImageResource等等,大家都可以自己擴展,這些方法都是提供設置View數據的。


好了,base封裝基本上完成了,接下來就是怎麼用了。

RecycleAdapterTest.class

import android.content.Context;
import java.util.List;
import css.lontano.coordinatorlayouttest.BaseRecycleView.BaseRecycleAdapter;
import css.lontano.coordinatorlayouttest.BaseRecycleView.BaseViewHolder;
import css.lontano.coordinatorlayouttest.javabean.BaseBean;
import css.lontano.coordinatorlayouttest.javabean.Person;

/**
 * Created by wangqi 2016/7/16.
 */
public class RecycleAdapterTest extends BaseRecycleAdapter {


    public RecycleAdapterTest(Context context, List list) {
        super(context, R.layout.recycle_item, list);
    }


    @Override
    protected  void convert(BaseViewHolder holder, T bean) {
        Person p = (Person) bean;
        holder.setText(R.id.text, p.getName());
    }
}

最後就是泛型的強轉,然後下面調用ViewHolder的設置數據,將資源id和數據傳遞過去,就設置好了。

哇塞,adapter這麼少的啊,真的好爽,我都佩服自己了。

主MAinActivity設置adapter就和普通設置數據一樣一樣的啦,基本沒什麼變化。

MainActivity.class

  recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        //模擬數據
        List list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Person p = new Person();
            p.setName(i+"ww");
            list.add(p);
        }

        RecycleAdapterTest adapter = new RecycleAdapterTest(this, list);
        recyclerView.setAdapter(adapter);
        adapter.setOnItemClickListner(new BaseRecycleAdapter.OnItemClickListner() {
            @Override
            public void onItemClickListner(View v, int position) {
                Toast.makeText(MainActivity.this,"單擊事件回調"+position,Toast.LENGTH_SHORT).show();
            }
        });
      adapter.setOnItemLongClickListner(new BaseRecycleAdapter.OnItemLongClickListner() {
          @Override
          public void onItemLongClickListner(View v, int position) {
              Toast.makeText(MainActivity.this,"長單擊事件回調"+position,Toast.LENGTH_SHORT).show();
          }
      });

item布局就是一個TextView,就沒有什麼了。

效果圖

這裡寫圖片描述


實力裝了一次,以前看別人寫這些代碼,感覺好高大上啊,其實真的沒有什麼啊=_=,自己動手,豐衣足食。暑期以來第一篇,之前忙著看 安卓優化方面的書,等看完了,有了自己的心得,再來寫一篇優化類的博文吧!!搞定!!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved