您的位置:首页 > 移动开发 > Android开发

【Android开发】自定义ListView,使用通用适配器,并实现ListView上的每一项和每一项上的按钮等控件同时监听

2015-05-27 21:25 1216 查看
ListView在Android开发中是比较常用的系统组件,但是有时候我们除了需要做ListView上每一行的点击监听事件之外,如果每一行上还有其他需要监听的控件例如Button、CheckBox等,就必须要进行特殊的处理。

本文自定义的ListView,实现了ListView的每一项和上面的Button按钮能同时监听点击事件(其他控件的做法与Button一样),并且使用通用适配器ListSimpleAdapter,相对于普通的ListActivity,更具扩展性,适配器上可以很容易添加更多各式的控件。

最终效果:








先写listsimpleadapter.xml,这个是ListView每一项的布局文件。如果想在每一项上要添加其他的控件,可以修改此文件。

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:padding="10dip"> <ImageView android:id="@+id/pic" android:layout_width="50dp" android:layout_height="50dp" android:padding="10dp" android:layout_gravity="top" android:background="@drawable/ava"/> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="right" android:paddingLeft="10dp" android:paddingTop="6dp" android:paddingBottom="6dp"> <TextView android:id="@+id/title" android:layout_width="180dip" android:layout_height="wrap_content" android:textSize="16dip" /> <TextView android:id="@+id/content" android:layout_width="180dip" android:layout_height="wrap_content" android:layout_below="@id/title" android:layout_marginTop="5dip" android:textSize="15dip" /> </RelativeLayout> <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right"> <!-- 注意此处需把Button的焦点focusable设置为不可见,CheckBox也一样 --> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:focusable="false"/> </LinearLayout> </LinearLayout>
自定义通用适配器的java代码。For循环中是对ListView中每一项中包含所有的组件进行判定每个组件的类型,从而去设置其数据。其中【instanceof】这个关键字是对Object 类型的判断。这里要特别指出,由于textview的某种原因,我也不是很清楚,只是经过测试,如果其他类似于Button、CheckBox等控件设置在textview的后面,其对应的代码将不执行,也就是说程序运行时把button和CheckBox都映射成了textview,故执行了textview中的代码。这个问题现在我也不知道原因所在。但是如果将Button、CheckBox等控件设置放在textview之前,代码正常运行。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

package
tabhost.demo.widget;

import
java.util.List;

import
java.util.Map;

import
tabhost.demo.TestActivity;

import
android.app.AlertDialog;

import
android.content.Context;

import
android.util.Log;

import
android.view.LayoutInflater;

import
android.view.View;

import
android.view.ViewGroup;

import
android.widget.BaseAdapter;

import
android.widget.Button;

import
android.widget.ImageView;

import
android.widget.TextView;

public
class
ListSimpleAdapter
extends
BaseAdapter
{

private
LayoutInflater
layoutinflater;

private
List<Map<String,Object>>
list;

private
int
layoutId;

private
String
flag[];

private
int
ItemId[];

public
ListSimpleAdapter(Context
context,List<Map<String,Object>>
list,

int
layoutId,String
flag[],int
ItemId[]){

this.layoutinflater
=
LayoutInflater.from(context);

this.list
=
list;

this.layoutId
=
layoutId;

this.flag
=
flag;

this.ItemId
=
ItemId;

}

//调用并显示view的条数

@Override

public
int
getCount(){

return
list.size();

}

@Override

public
Object
getItem(int
arg0){

return
0;

}

@Override

public
long
getItemId(int
arg0){

return
0;

}

@Override

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

convertView
=
layoutinflater.inflate(layoutId,
null);

//填充数据到对应的控件中,注意此处的textview应写在最后面,才能正常实例化控件

for(int
i=0;i<flag.length;i++){

if(convertView.findViewById(ItemId[i])
instanceof
ImageView){

ImageView
imageView
=
(ImageView)
convertView.findViewById(ItemId[i]);

imageView.setBackgroundResource((Integer)
list.get(position).get(flag[i]));

Log.e("type","imageview");

}

else
if(convertView.findViewById(ItemId[i])
instanceof
Button){

Button
button
=
(Button)
convertView.findViewById(ItemId[i]);

button.setText((String)
list.get(position).get(flag[i]));

button.setOnClickListener(

new
Button.OnClickListener()
{

@Override

public
void
onClick(View
v)
{

new
AlertDialog.Builder(TestActivity.TestActivity)

.setTitle("Button")

.setMessage("按钮触发监听事件!")

.show();

}

});

Log.e("type","button");

}

else
if(convertView.findViewById(ItemId[i])
instanceof
TextView){

TextView
textView
=
(TextView)
convertView.findViewById(ItemId[i]);

textView.setText((String)
list.get(position).get(flag[i]));

Log.e("type","textview");

}

else{

//预留其他控件处理,但必需写在TextView的前面

}

}

return
convertView;

}

}

写主界面的TestActivity:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

package
tabhost.demo;

import
java.util.ArrayList;

import
java.util.HashMap;

import
java.util.List;

import
java.util.Map;

import
tabhost.demo.widget.ListSimpleAdapter;

import
android.app.Activity;

import
android.app.AlertDialog;

import
android.os.Bundle;

import
android.view.View;

import
android.widget.AdapterView;

import
android.widget.ListView;

import
android.widget.AdapterView.OnItemClickListener;

public
class
TestActivity
extends
Activity

{

private
ListSimpleAdapter
listAdapter;

private
ListView
listView;
// 声明列表视图对象

private
List<Map<String,
Object>>
list; //
声明列表容器

public
static
TestActivity
TestActivity;

private
int
position_tmp; //position的临时存储变量

@Override

public
void
onCreate(Bundle
savedInstanceState)

{

super.onCreate(savedInstanceState);

TestActivity
=
this;

}

@Override

protected
void
onResume()
{

super.onResume();

//实例化列表视图

listView
=
new
ListView(this);

//实例化列表容器

list
=
new
ArrayList<Map<String,
Object>>();

try{

for(int
i=0;i<3;i++){

//实例一个列表数据容器,并将数据库数据添加到列表容器,每一个map的数据对应ListView中完整的一项

Map<String,
Object>
map
=
new
HashMap<String,
Object>();

map.put("pic",R.drawable.ava);

map.put("title","你好,我是标题");

map.put("content","测试内容,测试测试");

map.put("button","按钮"+Integer.toString(i));

list.add(map);

}

}

catch(Exception
e){

e.printStackTrace();}

//实例化适配器,具体可参见SimpleAdapter的使用

listAdapter
=
new
ListSimpleAdapter(this,
list,
R.layout.listsimpleadapter,
new
String[]
{

"pic",
"title",
"content","button"},
new
int[]
{R.id.pic,
R.id.title,
R.id.content,R.id.button});

listView.setAdapter(listAdapter);

//添加ListView每一行的点击监听事件,此处可设置监听处理操作

listView.setOnItemClickListener(new
OnItemClickListener()
{

public
void
onItemClick(AdapterView<?>
arg0,
View
arg1,

int
position,
long
id)
{

position_tmp
=
position;

new
AlertDialog.Builder(TestActivity)

.setTitle("ListView")

.setMessage("你点击了第"+Integer.toString(position_tmp)+"行!")

.show();

}

});

//显示列表视图

this.setContentView(listView);

}

}

至此,一个ListView就做完了。与传统的ListView,代码具有很高的重用性和扩展性,并且能很容易实现一个ListView。

代码附件,在上一篇的基础上我将第一个标签改成了ListView。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐