教你打造一個萬能的適配器

最近項目中 經常用listView和GridView ,可以說是項目中Listview GridView幾乎是必用的組件,Android也提供一套機制,爲這些控件綁定數據,那就是Adapter 最近抽了時間,自己也打造了一個萬能的適配器

看我們之前的一些寫法:

public class ImageViewAdapter2 extends RecyclerView.Adapter {PRivate SweatQuestryModel deviceDataBean; private Context context; private ArrayList urls = null; public ImageViewAdapter2(Context context, SweatQuestryModel deviceDataBean) { this.context = context; this.deviceDataBean = deviceDataBean; initImageUrl(deviceDataBean); } private void initImageUrl(SweatQuestryModel deviceDataBean) { urls = new ArrayList<>(); if(urls != null){ urls.addAll(deviceDataBean.getList()); } } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_imageview, null); MyViewHolder holder = new MyViewHolder(view); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, final int position) { GlideUtil.loadNetImg2(context, holder.image, urls.get(position) , R.drawable.default_square_image); holder.image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bundle bundle = new Bundle(); bundle.putStringArrayList("imgUrls",urls); bundle.putInt("position", position); bundle.putInt("type", PictureActivity.TYPE_NET_IMG); ActivityUtils.showActivity(context, PictureActivity.class, bundle); } }); } @Override public int getItemCount() { return deviceDataBean == null ? 0 : 9; } class MyViewHolder extends RecyclerView.ViewHolder { ImageView image; public MyViewHolder(View itemView) { super(itemView); image = (ImageView) itemView.findViewById(R.id.sweat_recycler_image); } } }

這樣用起來雖然還不錯,但每次都需要去繼承一個BaseAdapter,然後實現裏面的一大堆方法,而我們每次最關心的無非就是getView方法,其餘的方法幾乎都是相同代碼。這裏是不是就可以優化起來呢?在其次,我們在使用Adapter的時候,爲了優化性能,常常會創建一個Holder。而Holder裏面每次存放的都是View,對Holer的操作無非也就是初始化,綁定數據,複用。這裏是不是也可以抽取抽取? 如果我們封裝後:

/** * 類功能描述:
*v Viewholder * @author yuyahao * @version 1.0 修改時間:
修改備註:
*/ public class VolTeamAdapter extends CommonAdapter { private Context context; public VolTeamAdapter(Context context, List listDatas, int layoutId) { super(context, listDatas, layoutId); } @Override protected void fillData(ViewHolder holder, int position) { TextView actNum = holder.getView(R.id.team_item_active_num); TextView time = holder.getView(R.id.team_item_time); TextView title = holder.getView(R.id.team_item_title); ImageView icon = holder.getView(R.id.team_item_icon); Bean item = listDatas.get(position); actNum.setText(String.valueOf(item.getActiveSum()) + "個"); time.setText(String.valueOf(item.getTimeSun()) + "h"); title.setText(item.getName()); GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title); } }

這樣是不是簡單多了。每次 寫adapter都可以這樣用。

第一步:構造 BaseAdapter

** * 類功能描述:
*v 使用 * @author yuyahao * @version 1.0 修改時間:
修改備註:
*/ public class VolTeamAdapter extends CommonAdapter { private Context context; public VolTeamAdapter(Context context, List listDatas, int layoutId) { super(context, listDatas, layoutId); this.context = context; } @Override protected void fillData(ViewHolder holder, int position) { TextView actNum = holder.getView(R.id.team_item_active_num); TextView time = holder.getView(R.id.team_item_time); TextView title = holder.getView(R.id.team_item_title); ImageView icon = holder.getView(R.id.team_item_icon); Bean item = listDatas.get(position); actNum.setText(String.valueOf(item.getActiveSum()) + "個"); time.setText(String.valueOf(item.getTimeSun()) + "h"); title.setText(item.getName()); GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title); } }

好了,別賣關子了,直接上全部代碼。

/** * 類功能描述:
*v Viewholder * @author yuyahao * @version 1.0 修改時間:
修改備註:
*/ public abstract class CommonAdapter extends BaseAdapter { /*** 上下文的Context*/ protected Context mContext; /*** list的數據*/ protected List listDatas; /** Item佈局ID*/ protected int layoutId; public CommonAdapter(Context context, List listDatas, int layoutId) { this.mContext = context; this.listDatas = listDatas; this.layoutId = layoutId; } @Override public int getCount() { return listDatas == null ? 0 : listDatas.size(); } /** * 獲取當前點擊的Item的數據時用 * 在onItemClick中 parent.getAdapter().getItem(),獲取當前點擊的Item的數據 */ @Override public Object getItem(int position) { return listDatas.get(position); } @Override public long getItemId(int position) { return position; } /** *加載每一個Item,該方法是最關鍵的 */ @ Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = ViewHolder.getViewHolder(mContext, convertView, parent, layoutId, position); fillData(holder, position); return holder.getMConvertView(); } /** * * 抽象方法,用於子類實現,填充數據 * @param holder * @param position */ protected abstract void fillData(ViewHolder holder, int position); }

第二步Holer的通用化

/** * 類功能描述:
*v Viewholder * @author yuyahao * @version 1.0 修改時間:
修改備註:
*/ public class ViewHolder { private int mPosition; /** * View容器,用於存放Holer中的View * 據網上說是 SparseArray是這樣的 * SparseArray 是Android推薦使用的一個優化容器,相當於一個Map */ private SparseArray mViews; /** * Item佈局View convertView */ private View mConvertView; public ViewHolder(Context context, ViewGroup parent, int layoutId) { mViews = new SparseArray(); mConvertView = LayoutInflater.from(context).inflate(layoutId, null); mConvertView.setTag(this); } /** * 獲取ViewHolder * @param context * 上下文 * @param convertView * @param parent * @param layoutId * 佈局layout Id * @param * @return */ public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutId) { if (convertView == null) return new ViewHolder(context, parent, layoutId); return (ViewHolder) convertView.getTag(); } public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) { this.mViews = new SparseArray(); this.mPosition = position; this.mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false); this.mConvertView.setTag(this); } /** * 拿到一個ViewHolder對象 * @param context * @param convertView * @param parent * @param layoutId * @param position * @return */ public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutId, int position) { if (null == convertView) { return new ViewHolder(context, parent, layoutId, position); } else { ViewHolder holder = (ViewHolder) convertView.getTag(); holder.mPosition = position; return holder; } } /** * 獲取Holder中的ItemView * @param viewId * @return */ @SuppressWarnings("unchecked") publicT getView(int viewId) { View item = mViews.get(viewId); if (item == null) { item = mConvertView.findViewById(viewId); mViews.put(viewId, item); } return (T) item; } /** * 獲取convertView***/ public View getMConvertView() { return mConvertView; } }

這樣已經寫完。

第三步使用

/** * 類功能描述:
*v 使用 * @author yuyahao * @version 1.0 修改時間:
修改備註:
*/ public class VolTeamAdapter extends CommonAdapter { private Context context; public VolTeamAdapter(Context context, List listDatas, int layoutId) { super(context, listDatas, layoutId); this.context = context; } @Override protected void fillData(ViewHolder holder, int position) { TextView actNum = holder.getView(R.id.team_item_active_num); TextView time = holder.getView(R.id.team_item_time); TextView title = holder.getView(R.id.team_item_title); ImageView icon = holder.getView(R.id.team_item_icon); Bean item = listDatas.get(position); actNum.setText(String.valueOf(item.getActiveSum()) + ""); time.setText(String.valueOf(item.getTimeSun()) + ""); title.setText(item.getName()); GlideUtil.loadNetImgC(context,icon, item.getPhoto(), R.drawable.bg_app_title); } }

mainActivity:

public class MyTextActivity extends BaseActivity{ private Context cnt; @Bind(R.id.lv_list) ListView lv_list; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); addViewFillInRoot(R.layout.ctivity_mytext); ButterKnife.bind(this); cnt = this; initView(); } private void initView() { try { List list = DataTest.getMyTestList(); VolTeamAdapter volTeamAdapter = new VolTeamAdapter(cnt,list,R.layout.my_listr); lv_list.setAdapter(volTeamAdapter); } catch (Exception e) { e.printStackTrace(); } } }

xml

效果圖:


歡迎加入技術交流QQ羣:364595326

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章