android中的自定义复选框难度

时间:2012-04-18 17:00:46

标签: java android listview checkbox adapter

如何修改此imageCheckBoxAdapter代码以便在滚动时保持checkBox的状态(即使在滚动之后,所有选中的复选框仍应保持检查。还检查的变量是否需要存储在数组中)?

class imageCheckBoxAdapter extends ArrayAdapter<String>
{
private final Context context;
private final ArrayList<String> values;
private final Map< String, SmbFile> obj;
static ArrayList<Boolean> checks=new ArrayList<Boolean>();
public imageCheckBoxAdapter(Context context,ArrayList<String> values,Map< String, SmbFile>obj) 
{
    super(context, R.layout.row_checkbox, values);
    this.context = context;
    this.values = values;
    this.obj=obj;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.row_checkbox, parent, false);
    TextView textView = (TextView) rowView.findViewById(R.id.text1_check);
    textView.setText(values.get(position));
    ImageView imageView = (ImageView) rowView.findViewById(R.id.icon_image_check);
    try
    {
        if((obj.get(values.get(position)).isFile()))
        {
            imageView.setImageResource(R.drawable.view_file_icon);
        }
        else
        {
            imageView.setImageResource(R.drawable.view_folder_icon);
        }
    }
    catch (SmbException e) 
    {
        Toast.makeText(context,"Network error",Toast.LENGTH_SHORT).show();
        Log.d("id1", "error1");
        e.printStackTrace();
    }
    return rowView;
}
}

row_checkbox.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="5dp" >
    <CheckBox
    android:id="@+id/checkBox1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="false" />
 <ImageView
    android:id="@+id/icon_image_check"
    android:layout_width="50px"
    android:layout_height="50px"
    android:layout_marginLeft="5px"
    android:layout_marginRight="20px"
    android:layout_marginTop="5px"
    android:src="@drawable/view_file_icon" >
    </ImageView>
 <TextView
    android:id="@+id/text1_check"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@+id/label"
    android:textSize="30px" 
    android:typeface="sans">
    </TextView> 
</LinearLayout>

4 个答案:

答案 0 :(得分:5)

class imageCheckBoxAdapter extends ArrayAdapter<String> implements View.onClickListener
{
    private final Context context;
    private final ArrayList<String> values;
    private final Map< String, SmbFile> obj;
    private ArrayList<Boolean> checks=new ArrayList<Boolean>();

    public imageCheckBoxAdapter(Context context,ArrayList<String> values,Map< String, SmbFile>obj) 
    {
        super(context, R.layout.row_checkbox, values);
        this.context = context;
        this.values = values;
        this.obj=obj;

        for (int i = 0; i < values.size(); i++) {
            checks.add(i, false);
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.row_checkbox, parent, false);
        TextView textView = (TextView) rowView.findViewById(R.id.text1_check);
        CheckBox chk = (CheckBox) rowView.findViewById(R.id.checkBox1);
        textView.setText(values.get(position));
        ImageView imageView = (ImageView) rowView.findViewById(R.id.icon_image_check);
        try
        {
            if((obj.get(values.get(position)).isFile()))
            {
                imageView.setImageResource(R.drawable.view_file_icon);
            }
            else
            {
                imageView.setImageResource(R.drawable.view_folder_icon);
            }
        }
        catch (SmbException e) 
        {
            Toast.makeText(context,"Network error",Toast.LENGTH_SHORT).show();
            Log.d("id1", "error1");
            e.printStackTrace();
        }

        chk.setTag(Integer.valueOf(position));

        // Set a listener for the checkbox
        chk.setOnClickListener(this);

        //Sets the state of CB, since we have the list of checked CB
        chk.setChecked(checks.get(position));

        return rowView;
    }

    @Override
    public void onClick(View view) {
        Integer index = (Integer)view.getTag();
        boolean state = checks.get(index.intValue());

        checks.set(index.intValue(), !state);
    }
}

答案 1 :(得分:0)

我认为你需要在数组中存储值。对于每个checkBox,您可以设置changeListener来存储关联的复选框。

答案 2 :(得分:0)

我最近读过,不知道在哪里,有人问过类似的案例。

如果我理解正确,可能是因为CheckBox中的DataRepeaterItem控件不是数据绑定,而滚动复选框时会失去状态。

您可以尝试使用Viewstate来维护选中的值。我会尝试找到那篇帖子,看起来很有用。

答案 3 :(得分:0)

我认为您可以使用View.setTag方法保存列表中复选框的位置 在getView中引用你的复选框,如下所示:

CheckBox chk = (CheckBox) rowView.findViewById(R.id.checkBox1);

由于CheckBoxes是View的间接子类,因此它还有一个属性View.setTag,如下所示:

chk.setTag(Integer.valueOf(position));

然后将OnCheckedChangeListener设置为你的chk,如:

chk.setOnCheckedChangeListener(new OnCheckedChangeListener {
    public void onCheckedChanged(CompoundButton buttonView, boolean state) {
           Integer int = (Integer)buttonView.getTag();

           checks.set(int.intValue(), !boolean)
    }
});

由于布尔arraylist大小与值大小相同,因此指定位置对应复选框的确切位置

然后将此代码段添加到getView方法中:

if (checks.get(position)) {
  chk.setChecked(checks.get(position));
  // do some stuff if wanted..
} else {
  chk.setChecked(checks.get(position));
  // do some stuff if wanted..
}

我们做了片段,因为当listview向上或向下滚动时,会为看不见的行项调用getView。并且如果已经检查过,则更新行项。