我如何美元,显示旧的内容p $ pvent回收的ListView项目? [英] How do i prevent recycled ListView items from showing old content?
问题描述
我正在使用自定义ResourceCursorAdapter显示一个TextView和一个CheckBox一个ListView。 TextView的和CheckBox从游标得到他们的状态。我一直有与它的几个问题,最近一次是,当我滚动某些行是因为旧的TextViews文本和一些复选框被选中时,他们不应该。我添加了一个日志行,看看发生了什么事情,这只是我感到困惑了。
@覆盖
公共无效bindView(视图V,上下文CTX,光标C){
ViewHolder支架=(ViewHolder)v.getTag();holder.tv.setText(holder.tvText);
holder.cb.setChecked(holder.checked);
Log.d(TAG,在bindView,ROWID:+ holder.rowId +经文:+ holder.tvText);
}
@覆盖
公共查看NewView的(上下文CTX,光标C,VG的ViewGroup){ 视图V = li.inflate(布局,VG,FALSE);
ViewHolder持有人; 持有人=新ViewHolder();
holder.tv =(TextView中)v.findViewById([0]);
holder.tvText = c.getString(c.getColumnIndex(从[0]));
holder.cb =(复选框)v.findViewById([1]);
holder.rowId = c.getLong(c.getColumnIndex(从[2]));
holder.checked =(c.getString(c.getColumnIndexOrThrow(从[1]))。等于(N))?
假:真实的;
holder.cb.setOnClickListener(新OnClickListener(){
@覆盖
公共无效的onClick(视图v){
查看rowView =((查看)v.getParent());
ViewHolder支架=(ViewHolder)rowView.getTag(); holder.checked =(holder.checked ==假)?真假; smDb.setMemorized(holder.rowId);
rowView.setTag(保持器);
Log.d(TAG复选框,点击+ holder.rowId);
}});
Log.d(TAG,在NewView的,ROWID:+ holder.rowId);
v.setTag(保持器);
返回伏;
}
静态类ViewHolder {
TextView的电视;
串tvText;
复选框CB;
布尔检查;
龙ROWID;
}
日志输出
在NewView的,ROWID:26
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在NewView的,ROWID:27
在bindView,ROWID:27经文:马太福音6:24
在NewView的,ROWID:28
在bindView,ROWID:28经文:马太福音16:15-9
在NewView的,ROWID:29
在bindView,ROWID:29经文:马太福音25:40
在NewView的,ROWID:30
在bindView,ROWID:30经文:路加福音24:36-9
在NewView的,ROWID:31
在bindView,ROWID:31经文:约翰福音3:5
在NewView的,ROWID:32
在bindView,ROWID:32经文:约翰7:17
在NewView的,ROWID:33
在bindView,ROWID:33经文:约翰福音10:16
在NewView的,ROWID:34
在bindView,ROWID:34经文:约翰福音14:15
在NewView的,ROWID:26
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
在bindView,ROWID:26经文:马太福音5:14-6
这是造成您的问题的看法回收。
我不知道这是处理它的方式平稳的,但是这是我做到了。我做了一个数组来保存我的按钮状态信息,然后用它在我的getView方法,以确保状态保持,即使元素熄灭屏幕。
从我的项目中我有在每一行按键,可以有几个州(文本和彩色)的列表适配器的一个例子:
公共类ButtonCursorAdapter扩展SimpleCursorAdapter {
私人光标C; //在鼠标经过
私人上下文的背景下;
私人活动活动;
公共静态的String [] atdState; // String数组来保存按钮状态
公共静态的String [] atdRow; //匹配的字符串数组来保存分贝ROWID 公共ButtonCursorAdapter(上下文的背景下,INT布局,光标C,
的String []从,INT []到){
超(背景下,布局,C,从,到);
this.c = C;
this.context =背景;
this.activity =(活动)范围内;
atdState =新的String [c.getCount()]; //初始化按钮状态数组
atdRow =新的String [c.getCount()]; //初始化数据库ROWID阵列
c.moveToFirst();
INT I = 0;
而(c.isAfterLast()== FALSE){
如果(c.getString(3)== NULL){//如果状态为空,设置为
atdState [I] =;
}其他{
atdState [I] = c.getString(3); //设置状态,状态保存在数据库
}
atdRow [I] = c.getString(0); //从数据库设置ROWID
我++;
c.moveToNext();
}
} @覆盖
公共查看getView(INT位置,查看convertView,父母的ViewGroup){
如果(convertView == NULL)
convertView = View.inflate(背景下,
R.layout.listlayoutdoublebutton,NULL);
最终诠释POS =位置;
查看排= convertView;
c.moveToPosition(位置);
TextView的第一=(TextView中)convertView.findViewById(R.id.ListItem1);
去年的TextView =(TextView中)convertView.findViewById(R.id.ListItem2);
按钮atdButton =(按钮)convertView.findViewById(R.id.attendbutton);
first.setText(c.getString(1));
last.setText(c.getString(2));
atdButton.setText(atdState [位置]); //设置按钮状态
如果(atdState [位置] .equals(P)){//根据状态着色按钮
atdButton.getBackground()。setColorFilter(0xFF00FF00,
PorterDuff.Mode.MULTIPLY);
}否则如果(atdState [位置] .equals(T)){
atdButton.getBackground()。setColorFilter(0xFFFFFF00,
PorterDuff.Mode.MULTIPLY);
}否则如果(atdState [位置] .equals(E)){
atdButton.getBackground()。setColorFilter(0xFFFF6600,
PorterDuff.Mode.MULTIPLY);
}否则如果(atdState [位置] .equals(U)){
atdButton.getBackground()。setColorFilter(0xFFFF0000地址,
PorterDuff.Mode.MULTIPLY);
}其他{
。atdButton.getBackground()clearColorFilter();
}
atdButton.setFocusable(真);
atdButton.setClickable(真); atdButton.setOnClickListener(新OnClickListener(){
@覆盖
公共无效的onClick(查看视图){
按钮atdButton =(按钮)查看
.findViewById(R.id.attendbutton);
。字符串测试= atdButton.getText()的toString();
如果(test.equals()){
atdButton.setText(P);
atdState [POS] =P;
atdButton.getBackground()。setColorFilter(0xFF00FF00,
PorterDuff.Mode.MULTIPLY);
}否则如果(test.equals(P)){
atdButton.setText(T);
atdState [POS] =T;
atdButton.getBackground()。setColorFilter(0xFFFFFF00,
PorterDuff.Mode.MULTIPLY);
}否则如果(test.equals(T)){
atdButton.setText(E);
atdState [POS] =E;
atdButton.getBackground()。setColorFilter(0xFFFF6600,
PorterDuff.Mode.MULTIPLY);
}否则如果(test.equals(E)){
atdButton.setText(U);
atdState [POS] =U;
atdButton.getBackground()。setColorFilter(0xFFFF0000地址,
PorterDuff.Mode.MULTIPLY);
}否则如果(test.equals(U)){
atdButton.setText(P);
atdState [POS] =P;
atdButton.getBackground()。setColorFilter(0xFF00FF00,
PorterDuff.Mode.MULTIPLY);
}
}
});
返回(行);
}
}
在哪里我使用的setText和着色我的按钮,你会想setChecked或一些这样的,但希望这将指向你在正确的方向。
I'm working on a ListView that uses a custom ResourceCursorAdapter to display a TextView and a CheckBox. The TextView and CheckBox get their state from the Cursor. I've been having a few problems with it, the most recent being that when I scroll some of the rows have text from old TextViews and some CheckBoxes are selected when they shouldn't be. I've added a log line to see what's going on and that's just confused me more.
@Override
public void bindView(View v, Context ctx, Cursor c) {
ViewHolder holder = (ViewHolder)v.getTag();
holder.tv.setText(holder.tvText);
holder.cb.setChecked(holder.checked);
Log.d(TAG, "in bindView, rowId:" + holder.rowId + " Scripture:" + holder.tvText);
}
.
@Override
public View newView(Context ctx, Cursor c, ViewGroup vg){
View v = li.inflate(layout, vg, false);
ViewHolder holder;
holder = new ViewHolder();
holder.tv = (TextView)v.findViewById(to[0]);
holder.tvText = c.getString(c.getColumnIndex(from[0]));
holder.cb = (CheckBox)v.findViewById(to[1]);
holder.rowId = c.getLong(c.getColumnIndex(from[2]));
holder.checked = (c.getString(c.getColumnIndexOrThrow(from[1])).equals("n")) ?
false : true;
holder.cb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
View rowView = ((View)v.getParent());
ViewHolder holder = (ViewHolder)rowView.getTag();
holder.checked = (holder.checked == false) ? true : false;
smDb.setMemorized(holder.rowId);
rowView.setTag(holder);
Log.d(TAG, "check box clicked: " + holder.rowId);
}});
Log.d(TAG, "in newView, rowId:" + holder.rowId);
v.setTag(holder);
return v;
}
.
static class ViewHolder {
TextView tv;
String tvText;
CheckBox cb;
boolean checked;
Long rowId;
}
The Log output
in newView, rowId:26
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in newView, rowId:27
in bindView, rowId:27 Scripture:Matthew 6:24
in newView, rowId:28
in bindView, rowId:28 Scripture:Matthew 16:15-9
in newView, rowId:29
in bindView, rowId:29 Scripture:Matthew 25:40
in newView, rowId:30
in bindView, rowId:30 Scripture:Luke 24:36-9
in newView, rowId:31
in bindView, rowId:31 Scripture:John 3:5
in newView, rowId:32
in bindView, rowId:32 Scripture:John 7:17
in newView, rowId:33
in bindView, rowId:33 Scripture:John 10:16
in newView, rowId:34
in bindView, rowId:34 Scripture:John 14:15
in newView, rowId:26
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
in bindView, rowId:26 Scripture:Matthew 5:14-6
It's the view recycling that's causing your issue.
I'm not sure this is the smoothest way of handling it, but this is how I did it. I made an array to hold my button state information and then used it in my getView method to make sure the state is maintained even when an element goes off-screen.
Example from one of my projects where I have a list adapter with buttons on each row that can have several states (text and color):
public class ButtonCursorAdapter extends SimpleCursorAdapter {
private Cursor c; // Passed in cursor
private Context context;
private Activity activity;
public static String[] atdState; // String array to hold button state
public static String[] atdRow; // Matching string array to hold db rowId
public ButtonCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
this.c = c;
this.context = context;
this.activity = (Activity) context;
atdState = new String[c.getCount()]; // initialize button state array
atdRow = new String[c.getCount()]; // initialize db rowId array
c.moveToFirst();
int i = 0;
while (c.isAfterLast() == false) {
if (c.getString(3) == null) { // if state is null, set to " "
atdState[i] = " ";
} else {
atdState[i] = c.getString(3); // set state to state saved in db
}
atdRow[i] = c.getString(0); // set the rowId from the db
i++;
c.moveToNext();
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
convertView = View.inflate(context,
R.layout.listlayoutdoublebutton, null);
final int pos = position;
View row = convertView;
c.moveToPosition(position);
TextView first = (TextView) convertView.findViewById(R.id.ListItem1);
TextView last = (TextView) convertView.findViewById(R.id.ListItem2);
Button atdButton = (Button) convertView.findViewById(R.id.attendbutton);
first.setText(c.getString(1));
last.setText(c.getString(2));
atdButton.setText(atdState[position]); // set the button state
if (atdState[position].equals("P")) { // colorize the button depending on state
atdButton.getBackground().setColorFilter(0xFF00FF00,
PorterDuff.Mode.MULTIPLY);
} else if (atdState[position].equals("T")) {
atdButton.getBackground().setColorFilter(0xFFFFFF00,
PorterDuff.Mode.MULTIPLY);
} else if (atdState[position].equals("E")) {
atdButton.getBackground().setColorFilter(0xFFFF6600,
PorterDuff.Mode.MULTIPLY);
} else if (atdState[position].equals("U")) {
atdButton.getBackground().setColorFilter(0xFFFF0000,
PorterDuff.Mode.MULTIPLY);
} else {
atdButton.getBackground().clearColorFilter();
}
atdButton.setFocusable(true);
atdButton.setClickable(true);
atdButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Button atdButton = (Button) view
.findViewById(R.id.attendbutton);
String test = atdButton.getText().toString();
if (test.equals(" ")) {
atdButton.setText("P");
atdState[pos] = "P";
atdButton.getBackground().setColorFilter(0xFF00FF00,
PorterDuff.Mode.MULTIPLY);
} else if (test.equals("P")) {
atdButton.setText("T");
atdState[pos] = "T";
atdButton.getBackground().setColorFilter(0xFFFFFF00,
PorterDuff.Mode.MULTIPLY);
} else if (test.equals("T")) {
atdButton.setText("E");
atdState[pos] = "E";
atdButton.getBackground().setColorFilter(0xFFFF6600,
PorterDuff.Mode.MULTIPLY);
} else if (test.equals("E")) {
atdButton.setText("U");
atdState[pos] = "U";
atdButton.getBackground().setColorFilter(0xFFFF0000,
PorterDuff.Mode.MULTIPLY);
} else if (test.equals("U")) {
atdButton.setText("P");
atdState[pos] = "P";
atdButton.getBackground().setColorFilter(0xFF00FF00,
PorterDuff.Mode.MULTIPLY);
}
}
});
return (row);
}
}
Where I use setText and colorize my button you would want to setChecked or some such, but hopefully this will point you in the right direction.
这篇关于我如何美元,显示旧的内容p $ pvent回收的ListView项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!