ListView和CursorAdapter在滚动时不保持状态

时间:2014-12-18 09:10:54

标签: android android-listview android-cursoradapter

enter image description here

我有一个由Custom CursorAdapter填充的ListView,这个CursorAdapter里面有多个可选择/可操作的组件。

即使我在ListView中执行某些操作并滚动视图,状态也会丢失。

当我观察logcat时,我可以看到onCheckChangeListener的代码,即使没有单击按钮,也会每次调用这些组件。不确定是什么问题。

public class CalendarSettinsAdapater extends CursorAdapter {

    private int myClickPosition;
    private int myCheckPosition;
    DBHelper dbHelper;
    Context classContext;
    Cursor classCursor;
    ToggleButton mtoggle;
    CheckBox mCheckBox;
    TextView mTitle;
    Button mButton;
    boolean buttonEnable = false;

    ToggleEvent toggleEvent = new ToggleEvent();
    ToggleEventListener toggleEventLis = new ToggleEventListener();

    ListView calListView;

    @SuppressWarnings("deprecation")
    public CalendarSettinsAdapater(Context context, Cursor c) {
        super(context, c);
    }

    @SuppressLint("ResourceAsColor")
    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        Typeface tf = Typeface.createFromAsset(context.getAssets(),
                "fonts/Glegoo-Regular.ttf");

        calListView = (ListView) view.findViewById(R.id.calendarSettingsList);
        mTitle = (TextView) view.findViewById(R.id.calendarName);
        mtoggle = (ToggleButton) view.findViewById(R.id.silentToggle);
        mButton = (Button) view.findViewById(R.id.calendarExceptionEvents);
        mCheckBox = (CheckBox) view.findViewById(R.id.visibility);
        mtoggle.setTag(cursor.getPosition());
        mButton.setTag(cursor.getPosition());
        mCheckBox.setTag(cursor.getPosition());

        mTitle.setTypeface(tf);

        mTitle.setText(cursor.getString(cursor.getColumnIndex(cursor
                .getColumnName(1))));

        mTitle.setTextColor(Color.WHITE);

        classContext = context;
        classCursor = cursor;

        View v = view.findViewById(R.id.circleShape);
        final GradientDrawable rectCal = (GradientDrawable) v.getBackground();

        int key = Integer.parseInt(cursor.getString(cursor
                .getColumnIndex(cursor.getColumnName(0))));

        rectCal.setColor(cursor.getInt(cursor.getColumnIndex(cursor
                .getColumnName(4))));



        mCheckBox
                .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                    public void onCheckedChanged(CompoundButton buttonView,
                            boolean isChecked) {

                        int position = (Integer) buttonView.getTag();
                        myCheckPosition = position;
                        if (isChecked) {
                            updateDbToShow(classContext, classCursor);
                        } else {
                            updateDbToGreyed(classContext, classCursor);
                        }

                    }

                });


        mtoggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                final int position = (Integer) buttonView.getTag();
                myClickPosition = position;
                if (isChecked) {
                    updateDbToHandle(classContext, classCursor);
                } else {
                    updateDbToIgnore(classContext, classCursor);
                }
            }
        });



        setProperToggleButtonStatus(classContext, classCursor, mtoggle, mButton);

        setProperCheckBoxStatus(classContext, classCursor, mCheckBox, mTitle);

    }



    private void setProperCheckBoxStatus(Context context, Cursor cursor,
            CheckBox mcheckBox, TextView mTitle) {
        String calVisible = cursor.getString(cursor.getColumnIndex(cursor
                .getColumnName(5)));
        if (calVisible.equalsIgnoreCase("1")) {
            mcheckBox.setChecked(true);
            mtoggle.setEnabled(true);
            if (buttonEnable == true) {
                mButton.setEnabled(true);
            } else
                mButton.setEnabled(false);
        } else {
            mcheckBox.setChecked(false);
            mtoggle.setEnabled(true);
            mButton.setEnabled(true);
        }
    }

    private void setProperToggleButtonStatus(Context context, Cursor cursor,
            ToggleButton mtoggle, Button mButton) {

        dbHelper = new DBHelper(context);
        String calState1 = cursor.getString(cursor.getColumnIndex(cursor
                .getColumnName(2)));
        int calState = Integer.parseInt(calState1);
        int expEvent = dbHelper.getExceptionEvents(cursor.getString(cursor
                .getColumnIndex(cursor.getColumnName(0))), calState);
        String buttonLabel = String.valueOf(expEvent);
        if (calState1.equalsIgnoreCase("1")) {
            mtoggle.setChecked(true);
            if (expEvent < 1) {
                mButton.setEnabled(false);
                buttonEnable = false;
            } else {
                mButton.setEnabled(true);
                buttonEnable = true;
            }
            mtoggle.setEnabled(true);
            mButton.setText(buttonLabel);
            mButton.setTextColor(Color.WHITE);
            Drawable drawable = context.getResources().getDrawable(
                    R.drawable.ic_custom_ringer);
            drawable.setBounds(0, 0,
                    (int) (drawable.getIntrinsicWidth() * 0.40),
                    (int) (drawable.getIntrinsicHeight() * 0.40));
            mButton.setCompoundDrawables(drawable, null, null, null);
        } else {
            mtoggle.setChecked(false);
            if (expEvent < 1) {
                mButton.setEnabled(false);
                buttonEnable = false;
            } else {
                mButton.setEnabled(true);
                buttonEnable = true;
            }
            mtoggle.setEnabled(true);
            mButton.setText(buttonLabel);
            mButton.setTextColor(Color.WHITE);
            mButton.setCompoundDrawablesWithIntrinsicBounds(
                    R.drawable.ic_custom_silent, 0, 0, 0);
            Drawable drawable = context.getResources().getDrawable(
                    R.drawable.ic_custom_silent);
            drawable.setBounds(0, 0,
                    (int) (drawable.getIntrinsicWidth() * 0.40),
                    (int) (drawable.getIntrinsicHeight() * 0.40));
            mButton.setCompoundDrawables(drawable, null, null, null);
        }
    }

    private void updateDbToGreyed(Context context, Cursor cursor) {
        //update database
    }

    private void updateDbToShow(Context context, Cursor cursor) {
        //update database
    }

    protected void updateDbToHandle(Context context, Cursor cursor) {

        //update database
    }

    protected void updateDbToIgnore(Context context, Cursor cursor) {

        //update database
    }

    @SuppressWarnings("static-access")
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        classContext = context;
        classCursor = cursor;
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.calendar_settings_item, null);

        calListView = (ListView) view.findViewById(R.id.calendarSettingsList);
        mTitle = (TextView) view.findViewById(R.id.calendarName);
        mtoggle = (ToggleButton) view.findViewById(R.id.silentToggle);
        mButton = (Button) view.findViewById(R.id.calendarExceptionEvents);
        mCheckBox = (CheckBox) view.findViewById(R.id.visibility);

        setProperCheckBoxStatus(classContext, classCursor, mCheckBox, mTitle);
        setProperToggleButtonStatus(classContext, classCursor, mtoggle, mButton);
        return view;
    }


    private OnClickListener mCheckBoxListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            final int position = (Integer) v.getTag();
            myCheckPosition = position;
            if (mCheckBox.isChecked()) {
                updateDbToShow(classContext, classCursor);
            } else {
                updateDbToGreyed(classContext, classCursor);
            }

        }
    };

    private OnClickListener mToggleClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            final int position = (Integer) v.getTag();
            myClickPosition = position;
            if (mtoggle.isChecked()) {
                updateDbToHandle(classContext, classCursor);
            } else {
                updateDbToIgnore(classContext, classCursor);
            }
        }
    };

}][2]

2 个答案:

答案 0 :(得分:0)

您必须使用ViewHolder概念,只有在view为null时才初始化视图的所有组件,

View vi = convertView; // trying to reuse a recycled view
final ViewHolder holder;// = null;
final Item row_pos = rowItem.get(position);
if (vi == null) {
    // The view is not a recycled one: we have to inflate
    vi = mLayoutInflater.inflate(R.layout.menu_item_list_row, parent,
            false);
    holder = new ViewHolder();
    holder.txtTitle = (TextView) vi.findViewById(R.id.title);
    holder.txtPrice = (TextView) vi.findViewById(R.id.txtPrice);
    holder.edtQty = (EditText) vi.findViewById(R.id.edtQty);
    holder.edtQty.setInputType(InputType.TYPE_CLASS_NUMBER);
    vi.setTag(holder);
    // setting the image resource and title

} else {
    // View recycled !
    // no need to inflate
    // no need to findViews by id
    holder = (ViewHolder) vi.getTag();
}

return vi;

答案 1 :(得分:0)

尝试将其添加到xml文件中的复选框

 android:button="@null"
 android:focusable="false"
 android:focusableInTouchMode="false"

您需要通过检查布局标记来控制视图更改并保持对象的状态,即CheckBox。

 mCheckBox.setOnCheckedChangeListener(null);

我使用了以下方法。我希望它会有所帮助。

@SuppressLint("InflateParams")
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ViewHolder holder = null;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.listview_items, null);
            holder = new ViewHolder();
            holder.text_title = (TextView)v.findViewById(R.id.txt_exp_title);
            holder.text_description = (TextView)v.findViewById(R.id.txt_exp_desc);
            holder.icon = (ImageView)v.findViewById(R.id.img_exp_image);
            holder.star = (CheckBox)v.findViewById(R.id.img_exp_bookmark_selected);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
            holder.star.setOnCheckedChangeListener(null);
        }

        final POJOExponatListe o = filtered.get(position);
        if (o != null) {

            if (holder.text_title != null)
                holder.text_title.setText(o.getTitle());
            if (holder.text_description != null)
                holder.text_description.setText(o.getDescription());
            if (holder.icon != null)
                new AQuery(holder.icon).image(o.getImageUrl());
            Log.e(" Get VIEw ADaPTER", " " + o.getPosition());
            if (holder.star != null)
                holder.star.setChecked(o.getPosition());
            holder.star
                    .setOnCheckedChangeListener(new OnCheckedChangeListener() {

                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            if (isChecked) {
                                System.out.println(position + "  " + o.getID()
                                        + "--- :)");
                                dbHelper.toggleExponatBookmark(o.getID(),
                                        "true");
                                o.setPosition(true);

                            } else {
                                dbHelper.toggleExponatBookmark(o.getID(),
                                        "false");
                                o.setPosition(false);
                            }
                        }
                    });
        }

        return v;
    }