繁体   English   中英

为什么当我向上或向下滚动列表时,它在我的自定义光标适配器中激活了Switch侦听器?

[英]Why is that when I am scrolling up or down the list it activates a Switch listener in my custom cursor adapter?

我可以看到已经实现和调试的吐司,当我在列表上向上或向下滚动时,将从侦听器调用onCheckedChanged方法。 我正在回收视图(视图持有者模式),并且会想象回收视图会导致问题,但不确定该怎么做。 这是自定义光标适配器的代码-

public class MyCursorAdapter extends CursorAdapter {
private Context mContext;
private LayoutInflater cursorInflater;
private int res;
private String mgName;
private String mMfg;
private String mRarity;
private String mLoosePrice;
private String mgYear;
private String mYear_Mfg;
private int mOwned;
private boolean isOwned;
private Switch mySwitch;
private String mID;
private String mIDfinal;
private View v;
private int position = 1;


public MyCursorAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
    cursorInflater = (LayoutInflater) context.getSystemService(
            Context.LAYOUT_INFLATER_SERVICE);
    mContext = context;
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
    v = cursorInflater.inflate(R.layout.fragment_list, viewGroup, false);
    ViewHolder holder = new ViewHolder();
    holder.imageView = (ImageView) v.findViewById(R.id.game);
    holder.textView1 = (TextView) v.findViewById(R.id.game_Title);
    holder.textView2 = (TextView) v.findViewById(R.id.game_mfg);
    holder.textView3 = (TextView) v.findViewById(R.id.rarity_value);
    holder.textView4 = (TextView) v.findViewById(R.id.loose_cart_value);
    holder.switch1 = (Switch) v.findViewById(R.id.owned_switch);
    v.setTag(holder);
    return v;
}

@Override
public void bindView(final View view, Context context, Cursor cursor) {

//Determines row colors
    if (position % 2 == 1) {
        view.setBackgroundColor(Color.parseColor("#bbbbbb"));
        position++;
    } else {
        view.setBackgroundColor(Color.parseColor("#7b7b7b"));
        position++;
    }
    if (position > 10) {
        position = 1;
    }

    ViewHolder holder = (ViewHolder) view.getTag();

    String mboxArt = cursor.getString(cursor.getColumnIndex("_id"));
    mboxArt = "a" + mboxArt;
    res = context.getResources().getIdentifier(mboxArt, "drawable", context.getPackageName());
    mgName = cursor.getString(cursor.getColumnIndex("gName"));
    mMfg = cursor.getString(cursor.getColumnIndex("mfg"));
    mgYear = cursor.getString(cursor.getColumnIndex("gYear"));
    mYear_Mfg = mMfg + "," + mgYear;
    mRarity = cursor.getString(cursor.getColumnIndex("rarity"));
    mOwned = cursor.getInt(cursor.getColumnIndex("cart"));
    mLoosePrice = cursor.getString(cursor.getColumnIndex("lPrice"));
//        mID = cursor.getString(cursor.getColumnIndex("My_Collection_T._id"));
//        mIDfinal = "'" + mID + "'";

    if (mOwned == 1) {
        isOwned = true;
    } else {
        isOwned = false;
    }
    view.setTag(holder);


    holder.imageView.setImageResource(res);

    holder.textView1.setText(mgName);

    holder.textView2.setText(mYear_Mfg);

    holder.textView3.setText(mRarity);

    holder.textView4.setText(mLoosePrice);

    holder.switch1.setChecked(isOwned);

//Listener for owned switch
mySwitch = (Switch) view.findViewById(R.id.owned_switch);
mySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        ContentValues mNewValues = new ContentValues();
        TextView gameN = (TextView) view.findViewById(R.id.game_Title);
        CharSequence text = gameN.getText();
        text = "'" + text + "'";
        String gameName = text.toString();
        if (buttonView.isChecked()) {
            mNewValues.put("cart", 1);
            mNewValues.put("numCart", 1);
            gameName = "gName = " + gameName;
            mContext.getContentResolver().update(GamesContract.My_Collection_T.CONTENT_URI, mNewValues, gameName, null);

            ContentResolver resolver = mContext.getContentResolver();
            Cursor c = resolver.query(GamesContract.My_Collection_T.CONTENT_URI, null, null, null, null);
            //For debugging -
            if (c != null) {
                StringBuilder sb = new StringBuilder();
                dumpCursor(c, sb);
                String result = sb.toString();
                Toast.makeText(mContext,
                        result,
                        Toast.LENGTH_LONG
                ).show();
                c.close();
            }
            /////////////////////////
            mContext.getContentResolver().notifyChange(GamesContract.My_Collection_T.CONTENT_URI, null);
        } else {
            mNewValues.put("cart", 0);
            mNewValues.put("numCart", 0);
            gameName = "gName = " + gameName;
            mContext.getContentResolver().update(GamesContract.My_Collection_T.CONTENT_URI, mNewValues, gameName, null);

            ContentResolver resolver = mContext.getContentResolver();
            Cursor c = resolver.query(GamesContract.My_Collection_T.CONTENT_URI, null, null, null, null);
            //For debugging
            if (c != null) {
                StringBuilder sb = new StringBuilder();
                dumpCursor(c, sb);
                String result = sb.toString();
                Toast.makeText(mContext,
                        result,
                        Toast.LENGTH_LONG
                ).show();
                c.close();
            }
            /////////////////////////////////////////////
            mContext.getContentResolver().notifyChange(GamesContract.My_Collection_T.CONTENT_URI, null);
        }
    }
});

}

static class ViewHolder {
    ImageView imageView;
    TextView textView1;
    TextView textView2;
    TextView textView3;
    TextView textView4;
    Switch switch1;

}
}

不幸的是,即使您以编程方式进行调用,调用setChecked(boolean)也会触发侦听器。 也就是说,无法知道用户是否单击了它,或者您是否以编程方式更改了状态。

由于视图是回收的,因此首次创建视图时, owned_switch没有附加侦听器。 然后设置状态:

holder.switch1.setChecked(isOwned);

然后附加一个侦听器:

mySwitch.setOnCheckedChangeListener(...);

一切都按预期进行。 但是,在回收视图之后,它仍然具有附加的侦听器(在getView()中将相同的View作为convertView返回),因此调用:

holder.switch1.setChecked(isOwned);

将触发您先前在视图上设置的原始侦听器。 一种简单的解决方法是在调整检查状态并重置侦听器之前使侦听器为空:

mySwitch.setOnCheckedChangeListener(null);
holder.switch1.setChecked(isOwned);
mySwitch.setOnCheckedChangeListener(...);

另外,不确定为什么要为mySwitch创建新变量,因为它与holder.switch1相同。

如前所述,由于您正在回收相同的组件,所以当您向上或向下滚动时,根据显示的项目,切换按钮设置(ON / OFF)会改变。 因此,可能已在某个位置将该项目的true设置为true的切换按钮将显示另一个位置的另一个项目的false(您知道了),因为此开关已连接了一个侦听器。 这是使用ViewHolder模式时回收的预期结果。

您可以做的一件事是拥有一个重置onCheckedChanged()侦听器的方法。

暂无
暂无

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

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