databind替代viewholder

有所瞭解的都知道databinding出現的意義就在於系統自動幫助我們生成Data和View之間的connection.而在Adapter中出現的ViewHolder就是我們手動生成的connection,下面我們就來看看databinding是如何完全取代ViewHolder的角色吧。(在此之前請看如何配置環境,在上述鏈接裏有)

  

  1. public class DynamicActivity extends Activity {
       private View.OnClickListener itemClickListener;
       private GridView gridView;

       @Override
       protected void onCreate(Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_dynamic);
           itemClickListener = new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   Toast.makeText(getBaseContext(), v.getClass().getSimpleName(), Toast.LENGTH_SHORT).show();
               }
           };
           gridView = (GridView) findViewById(R.id.gridView);
           MMyAdapter adapter = new MMyAdapter(getBaseContext());
           adapter.setOnclickListener(itemClickListener);
           gridView.setAdapter(adapter);
       }
    }

 


         listener用於處理item的一些click事件,當然也可以直接寫到adapter裏面去,但是考慮到adapter還是比較純粹的處理view和data的關係,所以把這個還是放到了activity層。

        接着是activity_main.xml文件比較簡單就一個gridview


  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
       
    android:layout_width="match_parent"
       
    android:layout_height="match_parent">
       <GridView
           
    android:id="@+id/gridView"
           
    android:layout_width="match_parent"
           
    android:layout_height="wrap_content"
           
    android:numColumns="3" />
    </RelativeLayout>


   接着是比較關鍵的adapter


  1. /**
    * Created by zhangxiaang on 15/7/6.
    */
    public class MMyAdapter extends BaseAdapter {
       private Context mContext;
       private LayoutInflater inflater;
       private List<String> mlist;
       public View.OnClickListener itemClickListener;
       private ItemmBinding binding;

       public MMyAdapter(Context context) {
           this.mContext = context;
           inflater = LayoutInflater.from(context);
           mlist = new ArrayList<String>();
           for (int i = 0; i < 100; i++) {
               mlist.add(i, "item" + i);
           }
       }
       @Override
       public int getCount() {
           return mlist == null ? 0 : mlist.size();
       }

       @Override
       public Object getItem(int position) {
           return mlist.get(position);
       }

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

       @Override
       public View getView(int position, View convertView, ViewGroup parent) {
           if (convertView == null) {
               binding = DataBindingUtil.inflate(inflater, R.layout.itemm, parent, false);
               convertView = binding.getRoot();
               convertView.setTag(binding);
           } else {
               binding = (ItemmBinding) convertView.getTag();
           }
           binding.setVariable(BR.item, mlist.get(position));
           binding.setAdapter(this);
           return convertView;
       }
       public void setOnclickListener(View.OnClickListener itemClickListener) {
           this.itemClickListener = itemClickListener;
       }
    }

其中的item佈局如下:


  1. <layout xmlns:android="http://schemas.android.com/apk/res/android"
       
    xmlns:app="http://schemas.android.com/apk/res-auto">

       <data>
           <variable
               
    name="item"
               
    type="String" />
           <variable
               
    name="adapter"
               
    type="com.liangfeizc.databindingsamples.dynamic.MMyAdapter" />
       </data>

       <LinearLayout
           
    android:layout_width="match_parent"
           
    android:layout_height="match_parent"
           
    android:orientation="vertical">

           <TextView
               
    android:id="@+id/textView"
               
    android:layout_width="wrap_content"
               
    android:layout_height="wrap_content"
               
    android:clickable="true"
               
    app:text="@{item}"
               
    app:onClickListener="@{adapter.itemClickListener}"/>
       </LinearLayout>
    </layout>


可以看到的是在adapter中完全沒有 viewHolder的身影,在getView中,開始直接判斷當前的convertview是否爲空,進而來初始化這個binding對象,而convertView就是這個binding對象所對應的container的root view類似一個view-tree的rootView角色,然後同樣的給當前convertView打一個標籤方便後續取出,如果不爲空的話就直接取出當前convertView的binding對象。

處理完convertView的視圖部分接着就是處理convertView的數據部分,而數據部分應該在包含在convertview的binding中進行賦值。(感興趣的可以去看看生成的binding代碼,自動的替我們生成了<variable>標籤裏面數據的setter函數)

 

最後把設置完了view和data的converView直接返回就ok 啦,大家跑一邊看看databinding帶來的便利吧。

 

Ps:由於在rufi的案例中已經給了一個recyclerView的案例,但是我個人覺得recyclerView中已經封裝了ViewHolder,所以再使用databinding的話就顯得有點多餘了。畢竟databinding的存在意義就是取代掉viewHolder的。

 

歡迎各位提出自己的一些想法或者實現過程中遇到的問題。

發佈了19 篇原創文章 · 獲贊 40 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章