简体   繁体   English

滚动列表时,CheckBox会在ListView中自动检查

[英]CheckBox checked automatically in ListView when scrolling the list

I'm using a ListView in my app which contains some elements like textboxes and CheckBox in each list item. 我在我的应用程序中使用ListView ,其中包含每个列表项中的文本框和CheckBox等元素。 When I fill the first textbox the seventh one or any other random textbox automatically filled with the same value and same happens with CheckBox when I checked the CheckBox any other random CheckBox is also checked automatically . 当我填充第一个文本框时,第七个文本框或任何其他随机文本框自动填充 相同的值 ,当我检查 CheckBox时, CheckBox也会发生同样的事情,任何其他随机CheckBox也会自动检查

I'm unable to figure it out why it happens. 我无法弄明白为什么会发生这种情况。

My code below: 我的代码如下:

Listview content 列表视图内容

<!--- add your MY problem code comment -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/hyList"
    android:layout_width="fill_parent"
    android:layout_height="35sp"
    android:layout_gravity="top"
    android:orientation="horizontal" >

    <TableLayout
        android:id="@+id/tbltab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="100" >    
        <TableRow
            android:id="@+id/rowfooter"
            android:layout_width="fill_parent"
            android:layout_height="35sp"
            android:gravity="center_horizontal|bottom" >    
            <TextView
                android:id="@+id/txt_Hy_ID"
                android:layout_width="0sp"
                android:layout_height="35sp"
                android:textSize="1pt" >
            </TextView>    
            <TextView
                android:id="@+id/txt_HyID"
                android:layout_width="0sp"
                android:layout_height="35sp"
                android:textSize="1pt" >
            </TextView>    
            <TextView
                android:id="@+id/txt_Hy_Area"
                android:layout_width="200sp"
                android:layout_height="35sp"
                android:layout_gravity="center_vertical"
                android:gravity="left"
                android:textSize="8pt" >
            </TextView>    
            <CheckBox
                android:id="@+id/chkHyCondition"
                android:layout_width="60sp"
                android:layout_height="35sp"
                android:layout_gravity="center"
                android:saveEnabled="true" />    
            <EditText
                android:id="@+id/editTxtHyRemarks"
                android:layout_width="120sp"
                android:layout_height="35sp"
                android:layout_gravity="center_vertical|left"
                android:gravity="center_vertical|left"
                android:maxLength="25"
                android:saveEnabled="true"
                android:textSize="8pt" >
            </EditText>
        </TableRow>
    </TableLayout>    
</LinearLayout>

and Listview 和Listview

<ListView
   android:id="@+id/ListViewHy"
   android:layout_width="420sp"
   android:layout_height="100sp"
   android:layout_column="0"
   android:layout_span="3"
   android:clickable="true"
   android:saveEnabled="true"
   android:scrollbarSize="10sp"
   android:scrollbars="vertical" >
   </ListView>

I'm using this to bind my listview: 我用它来绑定我的listview:

private void FillGridHygiene() {
    LstViewHy = (ListView) findViewById(R.id.ListViewHy);
    clsDatabase dbh = new clsDatabase(this);
    dbh.openDataBase();
    Cursor cursor;
    cursor = dbh.getGridData("030");
    dbh.close();
    if (cursor != null) {
        int cnt = cursor.getCount();
        if (cnt > 0) {
            startManagingCursor(cursor);
            try {
                // -----------BindingListView----------------------------------------------------------------------------

                SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                        R.layout.hygiene_list, cursor, new String[] {
                                Audit_FSD_Tab.KEY_ROW_ID,
                                Audit_FSD_Tab.KEY_ID,
                                Audit_FSD_Tab.KEY_SHORT_NAME }, new int[] {
                                R.id.txt_Hy_ID, R.id.txt_HyID,
                                R.id.txt_Hy_Area });
                adapter.setViewResource(R.layout.hygiene_list);
                LstViewHy.setAdapter(adapter);
                LstViewHy.setTextFilterEnabled(true);
                LstViewHy.setFocusable(false);
                LstViewHy.setVisibility(View.VISIBLE);

            } catch (Exception ex) {
                ex.fillInStackTrace();
            }
        }

    }
}

Edit :1 编辑:1

API Level - 7 version - 2.1 API级别 - 7版本 - 2.1

The problem is in the design of your listview. 问题在于列表视图的设计。 You need to create a Custom Adapter and with the help of view holder and convertview recycle your views. 您需要创建自定义适配器,并在视图持有者和convertview的帮助下回收您的视图。 Listview List view using baseadapter Listview 列表视图使用baseadapter

This will help you in understanding the ListView concept and give an idea why - other random textbox automatically filled with the same value and same happens with checkbox when i checked the checkbox any other random checkbox is also checked automatically. 这将帮助您理解ListView概念并给出一个想法 - 其他随机文本框自动填充相同的值,当我选中复选框时,复选框也会发生相同的任何其他随机复选框也会自动检查。 Hope this will help you and help in designing your listview 希望这可以帮助您并帮助您设计列表视图

As the other said you'll have to make a custom Adapter and proper set/restore the values(for the CheckBox/EditText) for each row in the bindView . 正如另一个所说,你必须制作一个自定义Adapter并正确设置/恢复bindView每一行的值(对于CheckBox / EditText)。 Below is a simple example of an Adapter that stores the state: 下面是一个存储状态的Adapter的简单示例:

public class CustomAdapter extends SimpleCursorAdapter {

            // this will hold a mapping between the row ids and a special object that  will store the values for the EditText and CheckBox
    private HashMap<Long, StateSaver> status = new HashMap<Long, StateSaver>();

    public CustomAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to) {
        super(context, layout, c, from, to);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        super.bindView(view, context, cursor);
                    // get th id of the this row so we can use it as an identifier
        long theId = cursor.getLong(cursor.getColumnIndex("_id"));
        CheckBox ckb = (CheckBox) view.findViewById(R.id.checkBox1);
        ckb.setTag(new Long(theId));
                    // store the status of the CheckBox when it changes
        ckb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                Long theRealId = (Long) buttonView.getTag();
                StateSaver obj = status.get(theRealId);
                if (obj == null) {
                    obj = new StateSaver();
                    status.put(theRealId, obj);
                }
                obj.checked = isChecked;
            }
        });
        EditText et = (EditText) view.findViewById(R.id.editText1);
        et.setTag(new Long(theId));
                    // when the EditText losses focus it's time to store the value entered by the user
        et.setOnFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if(!hasFocus) {
                    Long theRealId = (Long) v.getTag();
                    StateSaver obj = status.get(theRealId);
                    if (obj == null) {
                        obj = new StateSaver();
                        status.put(theRealId, obj);
                    }
                    obj.currentInput = ((EditText) v).getText().toString();
                }
            }
        });
        StateSaver sv = status.get(theId);
        // setup the row with the correct data, either the default or what you've previously stored
        if (sv == null) {
            ckb.setChecked(false);
            et.setText("");
        } else {
            ckb.setChecked(sv.checked);
            et.setText(sv.currentInput);
        }

    }

    private class StateSaver {
        boolean checked = false;
        String currentInput = "";
    }

}

Also you'll want to set android:windowSoftInputMode="adjustPan" for the Activity containing the ListView . 此外,您还需要为包含ListViewActivity设置android:windowSoftInputMode="adjustPan"

My advice is to avoid using an EditText in a ListView row. 我的建议是避免在ListView行中使用EditText Also, try to improve your row layout: sp units should be used for text sizes only(use dp instead in any other places), don't use pt units, see if you really need the layout_weight attribute etc. 另外,尝试改进你的行布局: sp单位应仅用于文本大小(在任何其他地方使用dp ),不要使用pt单位,看看你是否真的需要layout_weight属性等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM