http://www.webplusandroid.com/creating-listview-with-edittext-and-textwatcher-in-android/
这个方法感觉很简单,原理:使用了final变量。
Today I am going to explain how to create a ListView with EditText and why will we need a TextWatcher to implement the same.
Before starting the topic, let us know why this topic is necessary.
Issue:
As we know ListView reuses the view of ListItem as we scroll the whole list.
So problem arises when we have a custom ListView with EditText where if we enter any value in the first EditText and start scrolling then the value of EditText one is copied to another the EditTexts one by one as we scroll the listview .
This happens as the listview reuses the view and as the other listitem from another view i.e. the view which is not seen scrolls upwards it reuses the old lists view and hence the old value of that view is seen in the new edittext.
The issue can be seen it the below image:
Now Scroll the List:
From above we can see that Text1 EdiText data is copied to Text10 and so on and so forth. The above issue can be resolved and the code to resolve the above issue is as follows:
First create your parent ListView layout:
lyt_listview_activity.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?
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"
>
<
ListView
android
:
id
=
"@+id/listViewMain"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"wrap_content"
>
<
/
ListView
>
<
/
LinearLayout
>
|
Then Create ListItem which will be your listview items:
lyt_listview_list.xml
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
|
<?
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
:
background
=
"@android:color/white"
android
:
orientation
=
"horizontal"
>
<
TextView
android
:
id
=
"@+id/textView1"
android
:
layout_width
=
"wrap_content"
android
:
textColor
=
"@android:color/black"
android
:
layout_height
=
"wrap_content"
android
:
text
=
"15dp"
/
>
<
EditText
android
:
id
=
"@+id/editText1"
android
:
layout_width
=
"match_parent"
android
:
layout_height
=
"wrap_content"
android
:
textColor
=
"@android:color/black"
android
:
ems
=
"10"
>
<
requestFocus
/
>
<
/
EditText
>
<
/
LinearLayout
>
|
Now this will be your Activity code:
ListviewActivity.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
|
package
com
.
example
.
testlistview
;
import
android
.
app
.
Activity
;
import
android
.
os
.
Bundle
;
import
android
.
text
.
Editable
;
import
android
.
text
.
TextWatcher
;
import
android
.
view
.
LayoutInflater
;
import
android
.
view
.
View
;
import
android
.
view
.
ViewGroup
;
import
android
.
widget
.
BaseAdapter
;
import
android
.
widget
.
EditText
;
import
android
.
widget
.
ListView
;
import
android
.
widget
.
TextView
;
public
class
ListviewActivity
extends
Activity
{
private
String
[
]
arrText
=
new
String
[
]
{
"Text1"
,
"Text2"
,
"Text3"
,
"Text4"
,
"Text5"
,
"Text6"
,
"Text7"
,
"Text8"
,
"Text9"
,
"Text10"
,
"Text11"
,
"Text12"
,
"Text13"
,
"Text14"
,
"Text15"
,
"Text16"
,
"Text17"
,
"Text18"
,
"Text19"
,
"Text20"
,
"Text21"
,
"Text22"
,
"Text23"
,
"Text24"
}
;
private
String
[
]
arrTemp
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
// TODO Auto-generated method stub
super
.
onCreate
(
savedInstanceState
)
;
setContentView
(
R
.
layout
.
lyt_listview_activity
)
;
arrTemp
=
new
String
[
arrText
.
length
]
;
MyListAdapter
myListAdapter
=
new
MyListAdapter
(
)
;
ListView
listView
=
(
ListView
)
findViewById
(
R
.
id
.
listViewMain
)
;
listView
.
setAdapter
(
myListAdapter
)
;
}
private
class
MyListAdapter
extends
BaseAdapter
{
@Override
public
int
getCount
(
)
{
// TODO Auto-generated method stub
if
(
arrText
!=
null
&&
arrText
.
length
!=
0
)
{
return
arrText
.
length
;
}
return
0
;
}
@Override
public
Object
getItem
(
int
position
)
{
// TODO Auto-generated method stub
return
arrText
[
position
]
;
}
@Override
public
long
getItemId
(
int
position
)
{
// TODO Auto-generated method stub
return
position
;
}
@Override
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
)
{
//ViewHolder holder = null;
final
ViewHolder
holder
;
if
(
convertView
==
null
)
{
holder
=
new
ViewHolder
(
)
;
LayoutInflater
inflater
=
ListviewActivity
.
this
.
getLayoutInflater
(
)
;
convertView
=
inflater
.
inflate
(
R
.
layout
.
lyt_listview_list
,
null
)
;
holder
.
textView1
=
(
TextView
)
convertView
.
findViewById
(
R
.
id
.
textView1
)
;
holder
.
editText1
=
(
EditText
)
convertView
.
findViewById
(
R
.
id
.
editText1
)
;
convertView
.
setTag
(
holder
)
;
}
else
{
holder
=
(
ViewHolder
)
convertView
.
getTag
(
)
;
}
holder
.
ref
=
position
;
holder
.
textView1
.
setText
(
arrText
[
position
]
)
;
holder
.
editText1
.
setText
(
arrTemp
[
position
]
)
;
holder
.
editText1
.
addTextChangedListener
(
new
TextWatcher
(
)
{
@Override
public
void
onTextChanged
(
CharSequence
arg0
,
int
arg1
,
int
arg2
,
int
arg3
)
{
// TODO Auto-generated method stub
}
@Override
public
void
beforeTextChanged
(
CharSequence
arg0
,
int
arg1
,
int
arg2
,
int
arg3
)
{
// TODO Auto-generated method stub
}
@Override
public
void
afterTextChanged
(
Editable
arg0
)
{
// TODO Auto-generated method stub
arrTemp
[
holder
.
ref
]
=
arg0
.
toString
(
)
;
}
}
)
;
return
convertView
;
}
private
class
ViewHolder
{
TextView
textView1
;
EditText
editText1
;
int
ref
;
}
}
}
|
This will be your manisfest file: Notice the tag windowSoftInputMode=”adjustPan” this will resolve keyboard focus issue in editText in listview
AndroidManifest.xml
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
|
<
manifest
xmlns
:
android
=
"http://schemas.android.com/apk/res/android"
package
=
"com.example.testlistview"
android
:
versionCode
=
"1"
android
:
versionName
=
"1.0"
>
<
uses
-
sdk
android
:
minSdkVersion
=
"8"
android
:
targetSdkVersion
=
"19"
/
>
<
application
android
:
allowBackup
=
"true"
android
:
icon
=
"@drawable/ic_launcher"
android
:
label
=
"@string/app_name"
>
<
activity
android
:
name
=
".ListviewActivity"
android
:
screenOrientation
=
"portrait"
android
:
windowSoftInputMode
=
"adjustPan"
>
<
intent
-
filter
>
<
action
android
:
name
=
"android.intent.action.MAIN"
/
>
<
category
android
:
name
=
"android.intent.category.LAUNCHER"
/
>
<
/
intent
-
filter
>
<
/
activity
>
<
/
application
>
<
/
manifest
>
|
In above activity code the TextWatcher code handles the issue of duplicating of one editText value to other. This will happen using a temporary variable which will store the previous value of editText with respect to its position and will set it when the same editText comes into focus or view.
Please comment if you have any doubts or any other issue. I will be happy to help…