展会信息港展会大全

[Android]对BaseAdapter中ViewHolder编写简化
来源:互联网   发布日期:2015-10-02 16:15:46   浏览:790次  

导读:在Android项目中,经常都会用到ListView这个控件,而相应的Adapter中getView()方法的编写有一个标准的形式,如下:复制代码1 @Override2 ...

在Android项目中,经常都会用到ListView这个控件,而相应的Adapter中getView()方法的编写有一个标准的形式,如下:

复制代码

1 @Override

2public View getView(int position, View convertView, ViewGroup parent) {

3ViewHolder holder;

4if(null == convertView){

5holder = new ViewHolder();

6LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

7convertView = mInflater.inflate(R.layout.item, null);

8holder.btn = (Button) convertView.findViewById(R.id.btn);

9holder.tv = (TextView) convertView.findViewById(R.id.tv);

10holder.iv = (TextView) convertView.findViewById(R.id.iv);

11

12convertView.setTag(holder);

13}else{

14holder = (ViewHolder) convertView.getTag();

15}

16final HashMap<String, Object> map = list.get(position);

17

18holder.iv.setImageResource(Integer.valueOf(map.get("iv").toString()));

19holder.tv.setText(map.get("tv").toString());

20

21holder.btn.setOnClickListener(new View.OnClickListener() {

22@Override

23public void onClick(View v) {

24Toast.makeText(context, map.get("btn").toString(), Toast.LENGTH_SHORT).show();

25}

26});

27

28return convertView;

29}

30

31 class ViewHolder{

32Button btn;

33ImageView iv;

34TextView tv;

35

36}

复制代码

以下是碎碎念(想直接看代码的,就跳过这段吧-_-!):

也就是说每次编写Adapter都需要编写class ViewHolder...、if(null == convertView){...等等。这些代码跟业务逻辑关系不大,没有必要每次都写重复代码,

所以,显然有简化代码的余地。

既然我们的需求是不需要重复编写ViewHolder等内部类,那就把它移到父类吧。

但是ViewHolder中在实际项目中有不同的View,那就用list存放起来吧,但是放在list中的话,怎么取出来?用index?显然不是好的方法,不是有Resource Id这玩意,通过这个取不就好了么?所以以Resource Id为key放在Map中比较合适,但是既然以int(Resource Id)为key,那自然而然想到使用SparseArray了。

然后再把if(null == converView)...这些代码统统移到父类中。

所以ABaseAdapter诞生了,代码如下:

复制代码

1 /**

2* 实现对BaseAdapter中ViewHolder相关的简化

3* Created with IntelliJ IDEA.

4* Author: wangjieemail:tiantian.china.2@gmail.com

5* Date: 14-4-2

6* Time: 下午5:54

7*/

8 public abstract class ABaseAdapter extends BaseAdapter{

9Context context;

10

11protected ABaseAdapter(Context context) {

12this.context = context;

13}

14

15protected ABaseAdapter() {

16}

17

18/**

19* 各个控件的缓存

20*/

21class ViewHolder{

22public SparseArray<View> views = new SparseArray<View>();

23

24/**

25* 指定resId和类型即可获取到相应的view

26* @param convertView

27* @param resId

28* @param <T>

29* @return

30*/

31<T extends View> T obtainView(View convertView, int resId){

32View v = views.get(resId);

33if(null == v){

34v = convertView.findViewById(resId);

35views.put(resId, v);

36}

37return (T)v;

38}

39

40}

41

42/**

43* 改方法需要子类实现,需要返回item布局的resource id

44* @return

45*/

46public abstract int itemLayoutRes();

47

48@Override

49public View getView(int position, View convertView, ViewGroup parent) {

50ViewHolder holder;

51if(null == convertView){

52holder = new ViewHolder();

53convertView = LayoutInflater.from(context).inflate(itemLayoutRes(), null);

54convertView.setTag(holder);

55}else{

56holder = (ViewHolder) convertView.getTag();

57}

58return getView(position, convertView, parent, holder);

59}

60

61/**

62* 使用该getView方法替换原来的getView方法,需要子类实现

63* @param position

64* @param convertView

65* @param parent

66* @param holder

67* @return

68*/

69public abstract View getView(int position, View convertView, ViewGroup parent, ViewHolder holder);

70

71 }

复制代码

如上代码:增加了一个itemLayoutRes()的抽象方法,该抽象方法提供给子类实现,返回item布局的resource id,为后面的getView方法提供调用。

可以看到上述代码中,在系统的getView方法中,进行我们以前在BaseAdapter实现类中所做的事(初始化converView,并绑定ViewHolder作为tag),然后抛弃了系统提供的getView方法,直接去调用自己写的getView抽象方法,这个getView方法是提供给子类去实现的,作用跟系统的getView一样,但是这个getView方法中携带了一个ViewHolder对象,子类可以通过这个对象进行获取item中的控件。

具体使用方式如下,比如创建了MyAdapter并继承了ABaseAdapter:

注意,在构造方法中需要调用父类的构造方法:

1 public MyAdapter(Context context, List<HashMap<String, Object>> list) {

2super(context);

3this.list = list;

4 }

即,以上的“super(context);”必须调用。

接着实现itemLayoutRes()方法,返回item的布局:

1 @Override

2 public int itemLayoutRes() {

3return R.layout.item;

4 }

getView方法中的实现如下:

复制代码

1 @Override

2 public View getView(int position, View convertView, ViewGroup parent, ViewHolder holder) {

3final HashMap<String, Object> map = list.get(position);

4

5Button btn = holder.obtainView(convertView, R.id.item_btn);

6ImageView iv = holder.obtainView(convertView, R.id.item_iv);

7TextView tv = holder.obtainView(convertView, R.id.item_tv);

8

9btn.setOnClickListener(new View.OnClickListener() {

10@Override

11public void onClick(View v) {

12Toast.makeText(context, map.get("btn").toString(), Toast.LENGTH_SHORT).show();

13}

14});

15

16iv.setImageResource(Integer.valueOf(map.get("iv").toString()));

17tv.setText(map.get("tv").toString());

18

19return convertView;

20}

复制代码

如上代码:调用holder.obtainView方法既可获取item中的控件;

赞助本站

人工智能实验室

相关热词: android开发

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港