【问题标题】:Is there any way to enable Edittext with Checkbox in Listview?有什么方法可以在 Listview 中启用带有 Checkbox 的 Edittext?
【发布时间】:2016-10-06 05:07:00
【问题描述】:

我正在尝试创建一个listview,每行都有一个checkboxedittext。我已使用 notifyDatasetChanged()checkbox 检查事件上启用了 edittext

但它会重置位置,这使得跟踪当前位置变得困难。我创建了一个实例变量来跟踪 checkbox 选中事件的当前位置,但这也重置为最后一个选中的项目。

checkbox 工作正常。它在选中时启用edittext,在取消选中时禁用,选中状态也很好。但问题是edittext 如果我使用listposition,则只能获得最后检查的值,如果我使用position,则last item

我的适配器如下:

public class ListViewAdapter extends ArrayAdapter<Model> implements TextWatcher{

private final List<Model> list;
private final Context context;
private int listPosition;
private ViewHolder newHolder = null;

public ListViewAdapter(Context context, List<Model> list) {
    super(context, R.layout.row, list);
    this.context = context;
    this.list = list;
}

public static class ViewHolder {
    public CheckBox mCheckBox;
    public EditText mEditText;
}

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {

    if (convertView == null) {
        LayoutInflater inflator = LayoutInflater.from(context);
        convertView = inflator.inflate(R.layout.row, null);
        newHolder = new ViewHolder();
        newHolder.mCheckBox = (CheckBox) convertView.findViewById(R.id.checkbox);
        newHolder.mEditText = (EditText) convertView.findViewById(R.id.txtValue);
        newHolder.mCheckBox.setText(list.get(position).getCheckText());
        newHolder.mEditText.setText(list.get(position).getValue());
        setEdit(false);

        convertView.setTag(newHolder);
        convertView.setTag(R.id.checkbox, newHolder.mCheckBox);
        convertView.setTag(R.id.txtValue, newHolder.mEditText);
    } else {
        newHolder = (ViewHolder) convertView.getTag();
    }

    newHolder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
            int getPosition = (int) compoundButton.getTag();
            list.get(getPosition).setSelected(compoundButton.isChecked());
            list.get(getPosition).setEnabled(compoundButton.isChecked());
            setEdit(compoundButton.isChecked());
            listPosition = getPosition;
            if(!compoundButton.isChecked()){
                list.get(getPosition).setValue("");
            }
            notifyDataSetChanged();
        }
    });

    newHolder.mCheckBox.setTag(position); 
    newHolder.mEditText.setTag(position);
    newHolder.mEditText.addTextChangedListener(this);
    setEdit(list.get(position).isEnabled());
    return convertView;
}

public void setEdit(boolean bool){
    newHolder.mEditText.setEnabled(bool);
    newHolder.mEditText.setFocusableInTouchMode(bool);
    newHolder.mEditText.setCursorVisible(bool);
}

@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

@Override
public void afterTextChanged(Editable s) {
    list.get(listPosition).setValue(s.toString());
}

}

【问题讨论】:

  • 我不确定您为什么需要设置标签并获取列表中的位置。 getView 方法有一个当前行的位置参数。此外,notifyDatasetChanged 仅在您在该位置编辑 Model 时才需要调用,所以也许您应该这样做,并以此为基础绘制视图
  • 查看这里以解决如何获取您的项目的位置mysamplecode.com/2012/07/android-listview-checkbox-example.html
  • @cricket_007 我需要调用notifyDatasetChanged 来启用/禁用EditText。一旦我们调用notifyDatasetChangedgetView 方法中给出的位置参数将重置为last position。我之前尝试过使用它,但它没有用。如果我检查一个项目并在相应的EditText 中输入文本,当前代码也可以正常工作,但如果任何用户在非当前行中输入文本,则会失败。
  • 可能是因为afterTextChanged 仅使用最后一个选中复选框的行,并且仅更新该模型。您可能还想在那里调用 notifyDatasetChanged

标签: android listview checkbox android-edittext android-checkbox


【解决方案1】:

您应该使用 arraylist 来存储检查的位置,而不是存储到单个整数中。在您的 adpater 中定义临时数组列表并创建 Hashmap 以存储在特定编辑文本中输入的值

ArrayList<String> selectedPosition = new ArrayList<String>();
HashMap<Integer, String> editHash = new HashMap<Integer, String>();

现在更新您的 getView() 方法,如下所示:

@Override
public View getView(final int position, View convertView, final ViewGroup parent) {

    if (convertView == null) {
        LayoutInflater inflator = LayoutInflater.from(context);
        convertView = inflator.inflate(R.layout.row, null);
        newHolder = new ViewHolder();
        newHolder.mCheckBox = (CheckBox) convertView.findViewById(R.id.checkbox);
        newHolder.mEditText = (EditText) convertView.findViewById(R.id.txtValue);
        newHolder.mCheckBox.setText(list.get(position).getCheckText());
        newHolder.mEditText.setText(list.get(position).getValue());
        setEdit(false);

        convertView.setTag(newHolder);
        convertView.setTag(R.id.checkbox, newHolder.mCheckBox);
        convertView.setTag(R.id.txtValue, newHolder.mEditText);
    } else {
        newHolder = (ViewHolder) convertView.getTag();
    }


    newHolder.mCheckBox.setTag(position); 
    newHolder.mEditText.setTag(position);
    //newHolder.mEditText.addTextChangedListener(this); Remove this
    setEdit(list.get(position).isEnabled());

    //Added Change here...Check if arraylist contains selectedposition or not?

    if(selectedPosition.contains(String.valueOf(position))){
           list.get(getPosition).setSelected(compoundButton.isChecked());
            list.get(getPosition).setEnabled(compoundButton.isChecked());
            setEdit(compoundButton.isChecked());
    }else{
           setEdit(false);
           list.get(getPosition).setValue("");
    }

   //Same way compare for edittext

   if(editHash.containsKey(Integer.parseInt(position))){
       newHolder.mEditText.setText(editHash.get(position));
    }else{
       newHolder.mEditText.setText("");
    }

    newHolder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {

        int position = (int) compoundButton.getTag();
        //Simply store and check selectedPosition

       if(!b)
           selectedPosition.remove(String.valueOf(position));
       else
           selectedPosition.add(String.valueOf(position));

       //And then update adapter
       notifyDataSetChanged();

        }
    });

   //Let's add Textwatcher for our Edittext
   newHolder.mEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {

             int position = (int) newHolder.mEditText.getTag();
             //Storing into Hashmap
             editHash.put(position, s.toString());

        }
    });


    return convertView;
}

【讨论】:

  • 为什么是字符串列表而不是整数?
  • @cricket_007 :是的,我们也可以获取整数列表。没关系。我只使用了字符串,因为当您应用添加和删除操作时,它会设置您要删除的数组列表的位置,而不是值容器。所以使用字符串有点容易
  • 我认为你是对的。添加和删​​除 int 基元将执行自动装箱
  • 感谢您的回答,但这并不能解决问题。首先,list.get(getPosition).setSelected()` 和 list.get(getPosition).setEnabled() 工作正常。这就是我能够通过检查启用/禁用EditText 的原因。您的代码仅确认是否选中了当前位置的复选框,这已经正常工作。我特别需要识别EditText 用户单击的行号/ID,以便TextWatcher 可以将文本保存到相应的EditText
  • @NagarajuGajula :是的,我得到了一些东西,我已经更新了我的答案。请检查一下。我用 hashmap 来存储特定编辑文本的值,然后比较它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 2023-03-29
  • 2020-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多