简体   繁体   English

Android:列表视图滚动期间未选中的复选框

[英]Android : Unchecked CheckBox during List View Scrolling

I have a ListView with a CheckBox inside its. 我有一个带有CheckBox的ListView。 I had clicked some CheckBoxes and still scrolling - perfect, UNTIL I decided to Scroll back. 我单击了一些CheckBoxes并仍在滚动-完美,直到我决定向后滚动。 At this time, the selected CheckBoxes aren't checked and others the wasn't checked had selected. 目前,未选中选中的复选框,而未选中的其他复选框则被选中。 I think that there are some bug at my code, please help me! 我认为我的代码中存在一些错误,请帮帮我! From now I thank you! 从现在开始,我谢谢你! Following the code: 遵循代码:

public class TableListAdapter extends
ArrayAdapter<String>
{
    private Context context;
    private int layoutId;
    private String[] numbers;
    private int btnColorId;
    public boolean[] listIsChecked;
    char activityOperation;


    int pos;

    public TableListAdapter(Context context, int layoutId, 
     String[] numbers, int btnColorId, char activityOperation)
    {
        super(context, layoutId, numbers);
        this.context = context;
        this.layoutId = layoutId;
        this.numbers = numbers;
        this.btnColorId = btnColorId;
        this.activityOperation = activityOperation;

        listIsChecked = new boolean[numbers.length];
    }

    @Override
    public View getView(int position, View view, ViewGroup parent)
    {
        Holder holder;
        pos = position;

        if (view == null)
        {
            holder = new Holder();
            view = LayoutInflater.from(context).inflate(layoutId, null);

            holder.image = (ImageView) view.findViewById(R.id.practice_list_itemImageView);
            holder.button = (Button) view.findViewById(R.id.practice_list_itemButton);
            holder.checkbox = (CheckBox) view.findViewById(R.id.practice_list_itemCheckBox);
        view.setTag(holder);
        }
        else
        {
            holder = (Holder) view.getTag();
        }


                holder.image.setImageResource(R.drawable.ic_launcher);
        holder.button.setText(numbers[position]);
            holder.button.setBackgroundResource(btnColorId);

              holder.checkbox.setChecked(listIsChecked[position]);

     holder.checkbox.setOnClickListener(new CheckBox.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            listIsChecked[pos] = ((CheckBox)v).isChecked();
        }
    });

    holder.button.setOnClickListener(new Button.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Intent intent = new Intent(context, ShowTableActivity.class);
            intent.putExtra("activityOperation", activityOperation);
            intent.putExtra("number", pos);
            context.startActivity(intent);
        }
    });

    return view;
}

class Holder
{
    ImageView image;
    Button button;
    CheckBox checkbox;
}
}









<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/practice_list_item_auxiliar"
android:gravity="center">

<Button
    android:id="@+id/practice_list_itemButton"
    android:textSize="@dimen/main_button_text"
    android:textStyle="bold"
    android:layout_width="0dp"
    android:layout_height="70dp"
    android:layout_weight="3"
    android:textColor="@android:color/white"
    android:padding="@dimen/main_button_padding"/>

<ImageView
    android:id="@+id/practice_list_itemImageView"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:layout_height="wrap_content"/>

<LinearLayout
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:orientation="vertical"
    android:gravity="center">
    <CheckBox
        android:id="@+id/practice_list_itemCheckBox"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>







 public class MainPracticeActivity  extends Activity
 {
String[] nums = {"1","2","3","4","5","6","7", "8", "9", "10"};
ListView lv;
char activityOperation;

ImageButton imageButtonLinkeable;
ImageButton imageButtonChoiceable;
ImageButton imageButtonTypeable;
ImageButton buttons[] = new ImageButton[3];

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_practice);

    activityOperation = getIntent().getCharExtra("activityOperation", '0');

    lv = (ListView) findViewById(R.id.main_practice_ListView);
    TableListAdapter tbl = new TableListAdapter
    (this, R.layout.practice_list_item, nums, getMainColor(activityOperation), activityOperation);
    lv.setAdapter(tbl);

    imageButtonLinkeable = (ImageButton)findViewById(R.id.main_practice_imagebutton_linkable);
    imageButtonChoiceable = (ImageButton)
            findViewById(R.id.main_practice_imagebutton_choiceable);
    imageButtonTypeable = (ImageButton)
            findViewById(R.id.main_practice_imagebutton_typeable);
    buttons[0] = imageButtonLinkeable;
    buttons[1] = imageButtonChoiceable;
    buttons[2] = imageButtonTypeable;

    //Set the default drawable resources to the game's buttons
    unselectButtons(buttons);

    //ImageButtons
    imageButtonLinkeable.setOnClickListener(new ImageButton.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            unselectButtons(buttons);
            selectButton(v);
        }
    });

    imageButtonChoiceable.setOnClickListener(new ImageButton.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            unselectButtons(buttons);
            selectButton(v);
        }
    });

    imageButtonTypeable.setOnClickListener(new ImageButton.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            unselectButtons(buttons);
            selectButton(v);
        }
    });
}

private int getMainColor(char activityOperation)
{
    int colorId = -1;

    switch(activityOperation)
    {
        case '+':
            colorId = R.color.add;
            break;

        case '-':
            colorId = R.color.subtract;
            break;

        case '*':
            colorId = R.color.multiply;
            break;

        case '/':
            colorId = R.color.divide;
            break;
    }
    return colorId;
}

private int getSelectedBackground(char activityOperation)
{
    int backgroundId = -1;

    switch(activityOperation)
    {
        case '+':
            backgroundId = R.drawable.circle_button_add_selected;
            break;

        case '-':
            backgroundId = R.drawable.circle_button_subtract_selected;
            break;

        case '*':
            backgroundId = R.drawable.circle_button_multiply_selected;
            break;

        case '/':
            backgroundId = R.drawable.circle_button_divide_selected;
            break;
    }
    return backgroundId;
}

private int getDefaultBackground(char activityOperation)
{
    int backgroundId = -1;

    switch(activityOperation)
    {
        case '+':
            backgroundId = R.drawable.circle_button_add_default;
            break;

        case '-':
            backgroundId = R.drawable.circle_button_subtract_default;
            break;

        case '*':
            backgroundId = R.drawable.circle_button_multiply_default;
            break;

        case '/':
            backgroundId = R.drawable.circle_button_divide_default;
            break;
    }
    return backgroundId;
}

private void unselectButtons(View...buttons)
{
    for(View cb : buttons)
    {
        ((ImageButton)cb).setBackgroundResource(getDefaultBackground(
        activityOperation));
    }
}

private void selectButton(View button)
{
    ((ImageButton)button).setBackgroundResource
    (getSelectedBackground(activityOperation));
}
 }

I think the problem might be the pos variable you're using inside your CheckBox click listener. 我认为问题可能是您在CheckBox Click监听器中使用的pos变量。

Imagine that getView() is called for position 0, then position 1, then position 2, etc (enough to fill up the list with all the visible positions). 想象一下,调用getView()的位置为0,然后是位置1,然后是位置2, getView()足够用所有可见位置填充列表)。 Once that's done, pos is equal to (let's say) 10 . 完成后, pos等于(假设) 10 What happens when you click the CheckBox at position 3? 当您单击位置3的复选框时会发生什么? I believe you will wind up setting listIsChecked[10] = true . 我相信您会设置listIsChecked[10] = true

You should get rid of the pos variable and just use the position argument passed to getView() . 您应该摆脱pos变量,而只需使用传递给getView()position参数。 You can make it be final if the compiler says it can't use a non-final variable in the click listener. 你可以把它变成final如果编译器说,它不能在点击监听器使用非最终变量。

@Override
public View getView(final int position, View view, ViewGroup parent)
{
    // ...

    holder.checkbox.setOnClickListener(new CheckBox.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            listIsChecked[position] = ((CheckBox)v).isChecked();
        }
    });

    // ...
}

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

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