【问题标题】:custom checkbox difficulty in androidandroid中的自定义复选框难度
【发布时间】:2012-04-30 03:39:50
【问题描述】:

如何修改此 imageCheckBoxAdapter 代码以在滚动时保持复选框的状态(即所有被选中的复选框即使在滚动后也应保持选中状态。而且选中的变量需要存储在数组中)?

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>

【问题讨论】:

    标签: java android listview checkbox adapter


    【解决方案1】:

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

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

    由于 CheckBox 是 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)
        }
    });
    

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

    然后将这个 sn-p 添加到您的 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..
    }
    

    我们执行 sn-p 是因为当 listview 向上或向下滚动时,会为看不见的行项目调用 getView。并更新是否已检查的行项目。

    【讨论】:

    • 嗨,乔伊,因为我是 android 编程新手,我发现很难将您的代码添加到我的代码 sn-p。那么您可以编辑我的代码并进行更改吗?
    • 嗨,我无法提问。他们阻止我提问,所以我使用元堆栈溢出来问我的问题。请仔细阅读我的问题并回答它。请快速发送您的回复。这对我的项目来说很紧迫
    【解决方案2】:
    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);
        }
    }
    

    【讨论】:

    • 嗨,这段代码中“状态”变量的用途是什么? @Override public void onClick(View view) { Integer index = (Integer)view.getTag();布尔状态 = checks.get(index.intValue()); check.set(index.intValue(), true); }
    • 当我尝试从外部读取“检查”静态变量时,它会抛出错误..为什么?
    • 不要访问检查尝试为检查值列表设置一个 getter 方法,然后我在上面编辑我的代码。
    【解决方案3】:

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

    如果我理解正确,这可能是因为CheckBox 控件未在DataRepeaterItem 中进行数据绑定,并且在滚动复选框时会丢失其状态。

    您可以尝试使用Viewstate 来维护检查值。我会试着找到那个帖子,它看起来很有信息。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 根据我上面的建议,选择 onClickListener 比选择 onCheckedChangedListener 更好,因为在 getView 中我们设置了复选框的状态,因为我们设置了复选框的状态,所以将调用 onCheckedChange 方法,因为我们的代码用于使用 arraylist 保存复选框的状态。当列表视图滚动时,结果将被污染,因为复选框的状态将再次更改
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      • 2011-04-27
      • 2019-09-14
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      相关资源
      最近更新 更多