可扩展列表扩展了包含复选框的cursorTreeAdapter

时间:2012-07-04 11:59:21

标签: android expandablelistview

问题在于保存滚动时复选框的状态。当我向下滚动或向上滚动时,由于屏幕重绘,某些未检查的项目会被检查。如果有人可以帮忙请。我将提供适配器的代码。

final class ExpAdapter extends CursorTreeAdapter {
        private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>();

        LayoutInflater mInflator;
        CursorTreeAdapter cur;

        class ViewHolder {
                    public TextView textView;
                    public CheckBox checkbox;
                }

        public ExpAdapter(Cursor cursor, Context context)
        {
            super(cursor, context);
            mInflator = LayoutInflater.from(context);
        }

        @Override
        protected void bindChildView(View view, Context context, final Cursor cursor,
                boolean isLastChild) {
            //TextView tvChild = (TextView) view.findViewById(android.R.id.text1);

               final TextView tvChild = (TextView) view.findViewById(R.id.label);
                tvChild.setText(cursor.getString(cursor
                        .getColumnIndex(tablename.columname...)));//child

               final CheckBox  chb = (CheckBox)view.findViewById(R.id.chkbox);

                chb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        // TODO Auto-generated method stub
                        if (buttonView.isChecked()) {
                            //buttonView.setChecked(true);
                            buttonView.setChecked(true);
                             groupcode = mCuror2.getInt(tablename.columname));
                             levelid = mCuror2.getInt(mCuror2.getColumnIndex(tablename.columname));

                             levelidarray.add(String.valueOf(levelid));
                             groupcodearray.add(String.valueOf(groupcode));


                             String x=(String)tvChild.getText();

                             array.add(x);
                            Toast.makeText(getApplicationContext(),""+ array, Toast.LENGTH_SHORT).show();
                            // do some operations here

                        }
                        else 
                                {
                            buttonView.setChecked(false);
                            //buttonView.setChecked(false);
                            //itemChecked.set(cursor.getPosition(), false);
                            // do some operations here
                            String x = (String)tvChild.getText();

                         levelidarray.remove(String.valueOf(levelid));
                         groupcodearray.remove(String.valueOf(groupcode));
                            array.remove((String)x);

                              Toast.makeText(getApplicationContext(),""+ array, Toast.LENGTH_SHORT).show();

                                }
                    }
                });


           }

       @Override
        protected void bindGroupView(View view, Context context, Cursor cursor,  boolean isExpanded)

           {

               TextView tvGrp = (TextView) view.findViewById(android.R.id.text1);
                tvGrp.setText(cursor.getString(cursor
                        .getColumnIndex(tablename.columname)));

               TextView code = (TextView) view.findViewById(android.R.id.text2);

            }

        @Override
        protected Cursor getChildrenCursor(Cursor groupCursor)
            {
               int groupId = groupCursor.getInt(groupCursor
                        .getColumnIndex(tablename.columname));

                String filter2 = " LEVEL_ID = " +groupId;
                mCuror2 = dbconnection....,filter2, null, null, null, null);

                return mCuror2;

            }


        @Override
        protected View newChildView(Context context, Cursor cursor,
                boolean isLastChild, ViewGroup parent)
        {

                View mView = mInflator.inflate(R.layout.listviewcheckbox, null);


                 final TextView tvChild = (TextView) mView.findViewById(R.id.label);

                tvChild.setText(cursor.getString(cursor
                        .getColumnIndex(tablename.columname)));

                CheckBox chb = (CheckBox)mView.findViewById(R.id.chkbox);

                chb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        // TODO Auto-generated method stub
                        if (buttonView.isChecked()) {
                            //buttonView.setChecked(true);
                            buttonView.setChecked(true);
                             groupcode = mCuror2.getInt(mCuror2.getColumnIndex(tablename.columname));
                             levelid = mCuror2.getInt(mCuror2.getColumnIndex(tablename.columname));

                             levelidarray.add(String.valueOf(levelid));
                             groupcodearray.add(String.valueOf(groupcode));


                             String x=(String)tvChild.getText();

                             array.add(x);
                            Toast.makeText(getApplicationContext(),""+ array, Toast.LENGTH_SHORT).show();
                            // do some operations here

                        }
                        else 
                                {
                            buttonView.setChecked(false);
                            //buttonView.setChecked(false);
                            //itemChecked.set(cursor.getPosition(), false);
                            // do some operations here
                            String x = (String)tvChild.getText();

                         levelidarray.remove(String.valueOf(levelid));
                         groupcodearray.remove(String.valueOf(groupcode));
                            array.remove((String)x);

                              Toast.makeText(getApplicationContext(),""+ array, Toast.LENGTH_SHORT).show();

                                }
                    }
                });

                return mView;


            }

        @Override
        protected View newGroupView(Context context, Cursor cursor,
                boolean isExpanded, ViewGroup parent)
            {   
                View mView = mInflator.inflate(
                        android.R.layout.simple_expandable_list_item_2, null);
                TextView tvGrp = (TextView) mView.findViewById(android.R.id.text1);
                tvGrp.setText(cursor.getString(cursor
                        .getColumnIndex(tablename.columname)));

                TextView code = (TextView)mView.findViewById(android.R.id.text2);
                code.setText(cursor.getString(cursor.getColumnIndex(tablename.columname)));

                return mView;
            }

2 个答案:

答案 0 :(得分:0)

如果未在数据库中存储已检查状态,则需要设置一个数组以跟踪已检查状态,然后使用该数组在适配器中进行设置。由于您需要组和子位置来引用它,我认为您必须使用getChildView方法而不是bindChildView来执行此操作。

声明一个类变量:

boolean[][] checkedStatus;

在构造函数中填充它:

public ExpAdapter(Cursor cursor, Context context) {      
    super(cursor, context);      
    mInflator = LayoutInflater.from(context);      
    checkedstatus = new boolean[cursor.getCount()][];                // initializae the first dimension of array
    for (int i=0; i<cursor.getCount(); i++){                         // iterate through the group cursor count
        cursor.moveToPosition(i);
        Cursor childCursor = ...                                     // get the childcursor for group cursor position i 
        checkedStatus[i] = new boolean[childcursor.getCount()];    // initialize the second dimension of array for group position i
        for (int j=0; j<childCursor.getCount(); j++){                // iterate through the childCursor for group position i
            checkedStatus[i][j] = false;                            // initialize the item to not checked for group position i, child position j
        }
    }
}    

然后在getChildView中使用它来设置状态:

CheckBox chb = (CheckBox)mView.findViewById(R.id.chkbox);
if (checkedStatus[groupPosition][childPosition] == true) {
    chb.setChecked(true);
} else {
    chb.setChecked(false);
}

请务必同时使用onCheckedChanged方法更新数组。

您的另一个选择是将已检查的状态存储在数据库中,然后您可以在bindView中检查该状态,并在更改时将其写入数据库并完成。当然,每次单击复选框时,必须访问数据库以写入/读取更改,因此我通常会避免使用此选项。

答案 1 :(得分:0)

我使用ResourceCursorTreeAdapter,我的解决方案是:

import android.util.SparseArray;

...

/**
 * A map of children IDs to selection state.
 */
private final SparseArray<Boolean> mSelectedChildrenMap = new SparseArray<Boolean>();

...

@Override
protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
    final int _id = cursor.getInt(...); // get ID

    Boolean selected;
    if (mSelectedChildrenMap.get(_id) == null) {
        selected = false;
        mSelectedChildrenMap.put(_id, selected);
    } else
        selected = mSelectedChildrenMap.get(_id);

    /*
     * Checkbox, you can use "view holder" approach...
     */
    CheckBox mCheckBox = (CheckBox) view.findViewById(...);
    mCheckBox.setOnCheckedChangeListener(null);
    mCheckBox.setChecked(selected);
    mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            mSelectedChildrenMap.put(_id, isChecked);
        }// onCheckedChanged()
    });

    ...
}// bindChildView()

...

@Override
public void notifyDataSetChanged(boolean releaseCursors) {
    super.notifyDataSetChanged(releaseCursors);
    /*
     * Only clears the map if releaseCursors == true.
     */
    if (releaseCursors)
        synchronized (mSelectedChildrenMap) {
            mSelectedChildrenMap.clear();
        }
}// notifyDataSetChanged()

@Override
public void notifyDataSetInvalidated() {
    super.notifyDataSetInvalidated();
    /*
     * Clears the map.
     */
    synchronized (mSelectedChildrenMap) {
        mSelectedChildrenMap.clear();
    }
}// notifyDataSetInvalidated()

希望它有所帮助: - )