简体   繁体   中英

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. 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 .

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
   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:

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

API Level - 7 version - 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. Listview List view using 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. 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 . Below is a simple example of an Adapter that stores the state:

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 .

My advice is to avoid using an EditText in a ListView row. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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