通用的ListView、RecyclerView的Adapter

jopen 9年前發布 | 33K 次閱讀 Android開發 移動開發 RecyclerView

Android Common Adapter

該庫用于簡化AbsListView類型與RecyclerView的Adapter構建,在ListViewAdapter和RecyclerAdapter封裝了固定的業務邏輯,使得用戶只需要實現變化的部分即可,簡化代碼,避免重復的模板代碼。

該庫的接口參考了base-adapter-helper,在此基礎上添加了RecyclerView Adapter的支持。兩種類型的Adapter之間通過橋接模式簡化代碼,參考ViewHolderImpl

</blockquote>

例如,我們要實現一個適用于AbsListView的Adapter時,通常代碼如下:

/**

  • Created by mrsimple on 28/9/15. */ public class FeedAdapter extends BaseAdapter { /**

    • 數據集 */ protected List<String> mDataSet = new ArrayList<String>();

      public FeedAdapter(List<String> datas) { mDataSet = datas; }

      @Override public String getItem(int position) { return mDataSet.get(position); }

      @Override public int getCount() { return mDataSet.size(); }

      @Override public long getItemId(int position) { return position; }

      @Override public View getView(int position, View convertView, ViewGroup parent) { FeedViewHolder viewHolder = null; if (convertView == null) {

       convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_type_1, parent, false);
       viewHolder = new FeedViewHolder(convertView);
       convertView.setTag(viewHolder);
      

      } else {

       viewHolder = (FeedViewHolder) convertView.getTag();
      

      } // 設置數據 viewHolder.textView.setText( getItem(position)); return convertView; }

      /**

    • Feed ViewHolder */ public static class FeedViewHolder { public ImageView imageView; public TextView textView;

      public FeedViewHolder(View itemView) {

       imageView = (ImageView) itemView.findViewById(R.id.imageview);
       textView = (TextView) itemView.findViewById(R.id.textview);
      

      } } }</pre>

      當Adapter的數量有幾個時,就會反復編寫getCount、getItem、getView等函數,但是它們的實現都是非常類似的,反復編寫這類代碼會使得代碼重復率很高。Common Adapter對這些邏輯進行了二次封裝,使得用戶可以更方便的構建Adapter類,示例如下:

      添加Gradle依賴

      在項目的build.gradle中添加上如下依賴:

      dependencies {
      // 其他依賴

      // Common Adapter的依賴 compile 'org.simple:adapter:1.0.0' }</pre></div>

      1、使用代碼

         /**

    • 初始化ListView */ private void initListView() { ListView listView = (ListView) findViewById(R.id.listview); final ListViewAdapter<String> adapter = new ListViewAdapter<String>(R.layout.list_item_type_1) {

       @Override
       protected void onBindData(GodViewHolder viewHolder, int position, String item) {
      
           viewHolder
                   .setText(R.id.textview, item)             // 設置文本內容
                   .setImageResource(R.id.imageview, R.drawable.big_smile) ; // 設置圖片資源
       }
      

      }; // 添加數據 adapter.addItems(mockDatas()); listView.setAdapter(adapter); // 設置ListView的點擊事件 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

       @Override
       public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
           Toast.makeText(MainActivity.this, "Click List : " + adapter.getItem(position), Toast.LENGTH_SHORT).show();
       }
      

      }); }</pre>

      針對于AbsListView類族的組件需要使用ListViewAdapter類型的Adapter,泛型參數就是單個實體類的數據類型。在構造 ListViewAdapter對象時覆寫onBindData函數完成數據的綁定即可。GodViewHolder中包含了各類View屬性的設置,具體請直接查看GodViewHolder中的setter函數。

      對于RecyclerView則需要使用RecyclerAdapter,使用方式與ListViewAdapter類似,示例代碼如下所示。

          /**

    • 初始化RecyclerView */ private void initRecyclerView() { RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); // 線性 recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

      // 初始化adapter final RecyclerAdapter<String> adapter = new RecyclerAdapter<String>(R.layout.list_item_type_1, mockDatas()) {

       @Override
       protected void onBindData(RecyclerViewHolder viewHolder, int position, String item) {
           viewHolder.setText(R.id.textview, item);
           ImageView imageView = viewHolder.findViewById(R.id.imageview);
           Glide
                   .with(viewHolder.getContext())
                   .load("http://img4.duitang.com/uploads/blog/201402/19/20140219232639_Cda2j.thumb.600_0.jpeg")
                   .into(imageView);
       }
      
       // 如果有多個布局,那么覆寫getItemViewType與getItemLayout即可
       @Override
       public int getItemViewType(int position) {
           return position % 5 == 0 ? 2 : 1;
       }
      
       @Override
       protected int getItemLayout(int type) {
           if (type == 2) {
               return R.layout.list_item_type_2;
           }
           return R.layout.list_item_type_1;
       }
      

      };

      // 設置RecyclerView的點擊事件 adapter.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() {

       @Override
       public void onItemClick(int position) {
           Toast.makeText(MainActivity.this, "Click Recycler : "
                   + adapter.getItem(position), Toast.LENGTH_SHORT).show();
       }
      

      }); recyclerView.setAdapter(adapter); }</pre>

      在使用Common Adapter時不需要擔心數據源發生改變導致列表數據不更新的問題,因為Adapter基類中將數據集設置為final,所有的數據都會添加到該數據集中;在增加、減少數據時也不需要調用notifyDataSetChanged,只需要調用Adapter對應的的addItem或者remove函數即可。

      2、效果

      https://github.com/bboyfeiyu/commonadapter

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!