一、前言
习惯很多时候决定了我们的做法,而做法一定程度上又在巩固我们的习惯。细想,这是一件很恐怖的事。所以很多时候要学会用一些新的方式去改变我们的习惯。做技术,亦如此。很多时候,我们写一个listview的adapter,总是会按照我们自己习惯的方式去写,布局简单的还好,布局一复杂起来,你就会看到你的类里面代码几百甚至上千行,这样维护起来是很可怕的。而我个人的编程风格是宁愿类多而不愿一个类里面的代码多。所以很多东西都喜欢抽离出去,尽量让代码之间具有的耦合性降到最低。今天这里要介绍的一种方式是将adapter里面的getview代码分离出一个类去,不要放在getview里面。让你的adapter变得更加清爽,维护起来更加清晰有效,这种方法开始是看到一个github上面的国外大神写的,经过理解,自己也写了一下,放在这里大家学习下。
二、实现
首先讲一下思想,看一下getView这个方法先,这里其实是通过inflate返回了一个view,对了,这里的view是在我们写的一个XML的文件解析出来的。所以我们能不能这样做,自定义一个view,而这个自定义的view就是我们那个listview的一个item的布局,然后这个view就单独作为一个类存在着,只要getView用到了,我们就new出这个自定义的view,让它return。确实,完全可以这样做的。而关于这种方式的好处,后面还会介绍到。
现在思想有了,具体怎样实现比较合理,就可以小思考下咯。尽量设计得通用,方便最好。
上代码解释:
1、首先定义一个接口,用来绑定控件,这里用泛型是为了通用性。
package com.kroc.adapter; /** * 绑定控件接口 * @author 林楷鹏 * @date 2014-12-9 下午9:45:25 */ public interface IAdapterView<T> { public void bind(int position, T item); }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/item_food_name_txtv" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_margin="5dip" android:layout_weight="1" /> <TextView android:id="@+id/item_food_num_txtv" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_margin="5dip" android:layout_weight="1" /> <Button android:id="@+id/item_food_get_btn" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_margin="5dip" android:text="获取" android:layout_weight="1" /> </LinearLayout>
package com.kroc.adapter; import android.content.Context; import android.content.Intent; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import com.kroc.adapterdemo.R; import com.kroc.main.FoodBO; import com.kroc.main.TestActivity; /** * item布局对应的view * @author 林楷鹏 * @date 2014-12-9 下午9:49:01 */ public class FoodListItemView extends LinearLayout implements IAdapterView<FoodBO>{ private Context mContext; private TextView nameTxtv; private TextView numTxtv; private Button getBtn; private FoodBO mFoodBO; public FoodListItemView(Context context) { super(context); this.mContext = context; init(); } private void init(){ View.inflate(getContext(), R.layout.lv_item_food, this); nameTxtv = (TextView)findViewById(R.id.item_food_name_txtv); numTxtv = (TextView)findViewById(R.id.item_food_num_txtv); getBtn = (Button)findViewById(R.id.item_food_get_btn); getBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent(mContext, TestActivity.class); intent.putExtra("food", mFoodBO); mContext.startActivity(intent); } }); } @Override public void bind(int position, FoodBO foodBO) { mFoodBO = foodBO; nameTxtv.setText(foodBO.getFoodName()); numTxtv.setText(foodBO.getFoodNum() + "份"); } }
package com.kroc.adapter; import android.content.Context; import android.view.View; import android.view.ViewGroup; import com.kroc.main.FoodBO; /** * @author 林楷鹏 * @description 食物列表适配 * @create 2014-11-24下午2:37:25 * */ public class MyAdapter extends CommonBaseAdapter<FoodBO> { private static final int ITEM_VIEW_TYPE_NUM = 2; private static final int ITEM_VIEW_TYPE_FOOD = 0; private static final int ITEM_VIEW_TYPE_IMAGE = 1; public MyAdapter(Context context) { super(context); } @Override public int getViewTypeCount() { return ITEM_VIEW_TYPE_NUM; } @Override public int getItemViewType(int position) { if(position % 3 == 0){//为了显示不同item布局 return ITEM_VIEW_TYPE_FOOD; }else{ return ITEM_VIEW_TYPE_IMAGE; } } @Override public View getView(int position, View convertView, ViewGroup parent) { IAdapterView<FoodBO> orderDetail = null; if(position % 3 == 0){ orderDetail = new FoodListItemView(mContext); }else{ orderDetail = new ImageListItemView(mContext); } orderDetail.bind(position, mList.get(position)); return (View) orderDetail; } }
另外这样做还有一个好处,就是代码的复用性,假如你有两个地方都用到同一个布局,那么通过这种方式,你就可以在两个地方new两个view就行,不用在两个地方将代码码两遍,那样很烦的。
其他代码不做多解释,还是老规矩。要了解的点击代码下载