ListView是支持多种布局的,例如,新浪微博中布局就分很多种,有的布局有图片,有的只有文字等。
先看下效果:
正在上传
1.首先定义两种布局类型:
adapter.xml:
<?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="vertical" >
<ImageView
android:id="@+id/mImg"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/mTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是适配器1" />
</RelativeLayout>
</LinearLayout>
adapter2
.xml:
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#ffffffff"
android:gravity="right"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:textColor="@android:color/black"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:textSize="28sp"
android:layout_height="wrap_content" />
</LinearLayout>
|
MainActivity.java:
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
|
package
info
.
dabu
.
multiplelayoutwithoutnoanotation
;
import
android
.
support
.
v7
.
app
.
AppCompatActivity
;
import
android
.
os
.
Bundle
;
import
android
.
widget
.
ListView
;
import
java
.
util
.
ArrayList
;
import
java
.
util
.
List
;
public
class
MainActivity
extends
AppCompatActivity
{
List
<ListViewItem>
mListViewItems
;
ListView
mListView
;
CustomAdapter
mAdapter
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
activity_main
)
;
mListView
=
(
ListView
)
findViewById
(
R
.
id
.
Lv
)
;
mListViewItems
=
new
ArrayList
<>
(
)
;
for
(
int
i
=
0
;
i
<
100
;
i
++
)
{
ListViewItem
temp
=
new
ListViewItem
(
)
;
int
x
=
(
int
)
(
Math
.
random
(
)
*
1000
)
;
if
(
x
%
2
==
0
)
{
temp
.
setType
(
0
)
;
temp
.
setString
(
String
.
valueOf
(
x
)
)
;
}
else
{
temp
.
setType
(
1
)
;
temp
.
setString
(
String
.
valueOf
(
x
)
)
;
}
mListViewItems
.
add
(
temp
)
;
}
mAdapter
=
new
CustomAdapter
(
this
,
mListViewItems
)
;
mListView
.
setAdapter
(
mAdapter
)
;
}
}
|
ListViewItem.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public
class
ListViewItem
{
private
String
mString
;
//布局的类型
private
int
mType
;
public
ListViewItem
(
)
{
}
public
ListViewItem
(
String
string
,
int
type
)
{
mString
=
string
;
mType
=
type
;
}
public
String
getString
(
)
{
return
mString
;
}
public
void
setString
(
String
string
)
{
mString
=
string
;
}
public
int
getType
(
)
{
return
mType
;
}
public
void
setType
(
int
type
)
{
mType
=
type
;
}
}
|
不同的CustomAdapter.java的写法:
第一种:
CustomAdapter.java:
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
|
package
info
.
dabu
.
multiplelayoutwithoutnoanotation
;
import
android
.
app
.
Activity
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
BaseAdapter
;
import
android
.
widget
.
ImageView
;
import
android
.
widget
.
TextView
;
import
java
.
util
.
List
;
/**
* Created by AlexY on 2016/4/1.
*
*
*
*/
public
class
CustomAdapter
extends
BaseAdapter
{
private
Activity
mActivity
;
private
List
<
ListViewItem
>
mList
;
public
CustomAdapter
(
)
{
}
public
CustomAdapter
(
Activity
activity
,
List
<ListViewItem>
list
)
{
mActivity
=
activity
;
mList
=
list
;
}
@Override
public
int
getCount
(
)
{
return
mList
.
size
(
)
;
}
@Override
public
Object
getItem
(
int
position
)
{
return
mList
.
get
(
position
)
;
}
@Override
public
long
getItemId
(
int
position
)
{
return
0
;
}
// 总共有几种布局
@Override
public
int
getViewTypeCount
(
)
{
return
2
;
}
// 获取Item的View的类型
@Override
public
int
getItemViewType
(
int
position
)
{
return
mList
.
get
(
position
)
.
getType
(
)
;
}
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
)
{
switch
(
getItemViewType
(
position
)
)
{
case
0
:
TextViewHolder
textViewHolder
;
if
(
convertView
==
null
)
{
convertView
=
LayoutInflater
.
from
(
mActivity
)
.
inflate
(
R
.
layout
.
type_textview
,
parent
,
false
)
;
textViewHolder
=
new
TextViewHolder
(
)
;
textViewHolder
.
textview
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
text
)
;
convertView
.
setTag
(
textViewHolder
)
;
}
else
{
textViewHolder
=
(
TextViewHolder
)
convertView
.
getTag
(
)
;
}
if
(
null
!=
textViewHolder
.
textview
)
{
textViewHolder
.
textview
.
setText
(
mList
.
get
(
position
)
.
getString
(
)
)
;
}
return
convertView
;
case
1
:
ImageViewHolder
imageViewHolder
;
if
(
convertView
==
null
)
{
convertView
=
LayoutInflater
.
from
(
mActivity
)
.
inflate
(
R
.
layout
.
type_imageview
,
parent
,
false
)
;
imageViewHolder
=
new
ImageViewHolder
(
)
;
imageViewHolder
.
imageView
=
(
ImageView
)
convertView
.
findViewById
(
R
.
id
.
image
)
;
convertView
.
setTag
(
imageViewHolder
)
;
}
else
{
imageViewHolder
=
(
ImageViewHolder
)
convertView
.
getTag
(
)
;
}
if
(
null
!=
imageViewHolder
.
imageView
)
{
imageViewHolder
.
imageView
.
setImageResource
(
R
.
mipmap
.
bangalore
)
;
}
return
convertView
;
//case语句中不要加break语句,因为break不会执行到。
default
:
break
;
}
return
convertView
;
}
//用来优化含TextView的布局
public
class
TextViewHolder
{
TextView
textview
;
}
// 用来优化含ImageView的布局
public
class
ImageViewHolder
{
ImageView
imageView
;
}
}
|
第二种:
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
package
info
.
dabu
.
multiplelayoutwithoutnoanotation
;
import
android
.
app
.
Activity
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
BaseAdapter
;
import
android
.
widget
.
ImageView
;
import
android
.
widget
.
TextView
;
import
java
.
util
.
List
;
/**
* Created by AlexY on 2016/4/1.
*
*
*
*/
public
class
CustomAdapter
extends
BaseAdapter
{
private
Activity
mActivity
;
private
List
<
ListViewItem
>
mList
;
public
CustomAdapter
(
)
{
}
public
CustomAdapter
(
Activity
activity
,
List
<ListViewItem>
list
)
{
mActivity
=
activity
;
mList
=
list
;
}
@Override
public
int
getCount
(
)
{
return
mList
.
size
(
)
;
}
@Override
public
Object
getItem
(
int
position
)
{
return
mList
.
get
(
position
)
;
}
@Override
public
long
getItemId
(
int
position
)
{
return
0
;
}
// 总共有几种布局
@Override
public
int
getViewTypeCount
(
)
{
return
2
;
}
// 获取Item的View的类型
@Override
public
int
getItemViewType
(
int
position
)
{
return
mList
.
get
(
position
)
.
getType
(
)
;
}
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
)
{
final
TextViewHolder
textViewHolder
;
final
ImageViewHolder
imageViewHolder
;
//必须将要设置的控件单独提取出来
TextView
textView
=
null
;
ImageView
imageView
=
null
;
if
(
convertView
==
null
)
{
switch
(
getItemViewType
(
position
)
)
{
case
0
:
convertView
=
LayoutInflater
.
from
(
mActivity
)
.
inflate
(
R
.
layout
.
type_textview
,
parent
,
false
)
;
textViewHolder
=
new
TextViewHolder
(
)
;
textView
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
text
)
;
textViewHolder
.
textview
=
textView
;
convertView
.
setTag
(
textViewHolder
)
;
break
;
case
1
:
convertView
=
LayoutInflater
.
from
(
mActivity
)
.
inflate
(
R
.
layout
.
type_imageview
,
parent
,
false
)
;
imageViewHolder
=
new
ImageViewHolder
(
)
;
imageView
=
(
ImageView
)
convertView
.
findViewById
(
R
.
id
.
image
)
;
imageViewHolder
.
imageView
=
imageView
;
convertView
.
setTag
(
imageViewHolder
)
;
break
;
default
:
break
;
}
}
else
{
switch
(
getItemViewType
(
position
)
)
{
case
0
:
textViewHolder
=
(
TextViewHolder
)
convertView
.
getTag
(
)
;
textView
=
textViewHolder
.
textview
;
break
;
case
1
:
imageViewHolder
=
(
ImageViewHolder
)
convertView
.
getTag
(
)
;
imageView
=
imageViewHolder
.
imageView
;
break
;
}
}
switch
(
getItemViewType
(
position
)
)
{
case
0
:
//虽然textview不会为null,但检查下还是必要的
if
(
null
!=
textView
)
{
textView
.
setText
(
mList
.
get
(
position
)
.
getString
(
)
)
;
}
break
;
case
1
:
//虽然imageView不会为null,但检查下还是必要的
if
(
null
!=
imageView
)
{
imageView
.
setImageResource
(
R
.
mipmap
.
bangalore
)
;
}
break
;
}
return
convertView
;
}
//用来优化含TextView的布局
public
class
TextViewHolder
{
TextView
textview
;
}
// 用来优化含ImageView的布局
public
class
ImageViewHolder
{
ImageView
imageView
;
}
}
|
剩下的问题:
上面两种虽然可以实现功能,但是有个问题,上面中才两种布局,如果有5种布局,则CustomAdapter.java中代码就很长了。所以我们需要将getView()中的代码拆解到多个文件中。
第三种写法:
先定义一个接口DelegateAdapter,这个接口有个方法专门用来返回不同的布局:
DelegateAdapter.java:
1
2
3
4
5
6
7
8
9
|
/**
* Created by AlexY on 2016/4/2.
* 这个接口的作用就是定义一个方法用来返回不同的View
*/
public
interface
DelegateAdapter
{
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
,
LayoutInflater
inflater
,
Object
item
)
;
}
|
然后有几个布局,就写个类来实现接口DelegateAdapter:
TextDelegateAdapter.java:
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
|
package
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
Adapter
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
TextView
;
import
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
DelegateAdapter
;
import
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
ListViewItem
;
import
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
R
;
/**
* 含TextView的
*/
public
class
TextDelegateAdapter
implements
DelegateAdapter
{
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
,
LayoutInflater
inflater
,
Object
item
)
{
final
TextViewHolder
textViewHolder
;
if
(
convertView
==
null
)
{
convertView
=
inflater
.
inflate
(
R
.
layout
.
type_textview
,
parent
,
false
)
;
textViewHolder
=
new
TextViewHolder
(
)
;
textViewHolder
.
textview
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
text
)
;
convertView
.
setTag
(
textViewHolder
)
;
}
else
{
textViewHolder
=
(
TextViewHolder
)
convertView
.
getTag
(
)
;
}
if
(
null
!=
textViewHolder
.
textview
)
{
textViewHolder
.
textview
.
setText
(
(
(
ListViewItem
)
item
)
.
getString
(
)
)
;
}
return
convertView
;
}
//用来优化含TextView的布局
public
class
TextViewHolder
{
TextView
textview
;
}
}
|
ImageDelegateAdapter.java:
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
|
package
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
Adapter
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
ImageView
;
import
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
DelegateAdapter
;
import
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
R
;
/**
* 含ImageView的布局
*/
public
class
ImageDelegateAdapter
implements
DelegateAdapter
{
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
,
LayoutInflater
inflater
,
Object
item
)
{
final
ImageViewHolder
imageViewHolder
;
if
(
convertView
==
null
)
{
convertView
=
inflater
.
inflate
(
R
.
layout
.
type_imageview
,
parent
,
false
)
;
imageViewHolder
=
new
ImageViewHolder
(
)
;
imageViewHolder
.
imageView
=
(
ImageView
)
convertView
.
findViewById
(
R
.
id
.
image
)
;
convertView
.
setTag
(
imageViewHolder
)
;
}
else
{
imageViewHolder
=
(
ImageViewHolder
)
convertView
.
getTag
(
)
;
}
if
(
null
!=
imageViewHolder
.
imageView
)
{
imageViewHolder
.
imageView
.
setImageResource
(
R
.
mipmap
.
bangalore
)
;
}
return
convertView
;
}
// 用来优化含ImageView的布局
public
class
ImageViewHolder
{
ImageView
imageView
;
}
}
|
现在的CustomAdapter.java比上面两种写法要简洁和干净些。
CustomAdapter.java:
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
package
info
.
dabu
.
multiplelayoutwithoutnoanotation
;
import
android
.
app
.
Activity
;
import
android
.
support
.
v4
.
util
.
LongSparseArray
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
BaseAdapter
;
import
java
.
util
.
List
;
import
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
Adapter
.
ImageDelegateAdapter
;
import
info
.
dabu
.
multiplelayoutwithoutnoanotation
.
Adapter
.
TextDelegateAdapter
;
/**
* Created by AlexY on 2016/4/1.
*
*
*
*/
public
class
CustomAdapter
extends
BaseAdapter
{
private
LongSparseArray
<DelegateAdapter>
mDelegateAdapterSparseArray
;
private
Activity
mActivity
;
private
List
<
ListViewItem
>
mList
;
private
LayoutInflater
mLayoutInflater
;
public
CustomAdapter
(
)
{
}
public
CustomAdapter
(
Activity
activity
,
List
<ListViewItem>
list
)
{
mActivity
=
activity
;
mList
=
list
;
mLayoutInflater
=
LayoutInflater
.
from
(
mActivity
)
;
mDelegateAdapterSparseArray
=
new
LongSparseArray
<>
(
)
;
DelegateAdapter
delegateAdapter0
=
new
TextDelegateAdapter
(
)
;
mDelegateAdapterSparseArray
.
put
(
0
,
delegateAdapter0
)
;
DelegateAdapter
delegateAdapter1
=
new
ImageDelegateAdapter
(
)
;
mDelegateAdapterSparseArray
.
put
(
1
,
delegateAdapter1
)
;
}
@Override
public
int
getCount
(
)
{
return
mList
.
size
(
)
;
}
@Override
public
Object
getItem
(
int
position
)
{
return
mList
.
get
(
position
)
;
}
@Override
public
long
getItemId
(
int
position
)
{
return
0
;
}
// 总共有几种布局
@Override
public
int
getViewTypeCount
(
)
{
return
mDelegateAdapterSparseArray
.
size
(
)
;
}
// 获取Item的View的类型
@Override
public
int
getItemViewType
(
int
position
)
{
return
mList
.
get
(
position
)
.
getType
(
)
;
}
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
)
{
int
itemType
=
getItemViewType
(
position
)
;
switch
(
itemType
)
{
case
0
:
return
mDelegateAdapterSparseArray
.
get
(
itemType
)
.
getView
(
position
,
convertView
,
parent
,
mLayoutInflater
,
getItem
(
position
)
)
;
case
1
:
return
mDelegateAdapterSparseArray
.
get
(
itemType
)
.
getView
(
position
,
convertView
,
parent
,
mLayoutInflater
,
getItem
(
position
)
)
;
default
:
break
;
}
return
convertView
;
}
}
|
其余的MainActivity.java和布局文件都和上面一样。