【问题标题】:EditText in ListView loses content on scroll in ListViewListView 中的 EditText 在 ListView 中滚动时丢失内容
【发布时间】:2014-11-19 12:46:23
【问题描述】:

我正在开发一个用户填写报告和投票的应用程序。在一个活动中,我有一个 ListView,其中子项包含 EditTexts、Checkbox 和 TextView。

EditTexts 和 Checkbox 的问题是在滚动时,它们拥有的内容会丢失。我可以通过将检查状态保存在数组中来解决 Checkbox 问题,但我无法解决 EditTexts 的问题。我知道关于这个特定问题存在一些问题,但他们提供的解决方案似乎不起作用。所以这是我的适配器:

public class DiveProfileAdapter extends ArrayAdapter<DiveProfile> {

    private Context mContext;
    private List<DiveProfile> mTasks;
    ViewHolder holder;

    private ArrayList<Boolean> itemChecked = new ArrayList<>(); //for saving checkbox values

    public DiveProfileAdapter(Context context, List<DiveProfile> objects) {
        super(context, R.layout.row_dive_profile_divers_list_item, objects);
        this.mContext = context;
        this.mTasks = objects;

        for (int i = 0; i < this.getCount(); i++) {
            itemChecked.add(i, false); // initializes all items value with false
        }
    }

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

        if (convertView == null) {
            LayoutInflater mLayoutInflater = LayoutInflater.from(mContext);
            convertView = mLayoutInflater.inflate(R.layout.row_dive_profile_divers_list_item, null);

            holder = new ViewHolder();
            holder.diverAttended = (CheckBox) convertView.findViewById(R.id.diver_attended_checkbox);   
            holder.diveTime = (EditText) convertView.findViewById(R.id.dive_time_edit_text);
            holder.depth = (EditText) convertView.findViewById(R.id.depth_edit_text);

            convertView.setTag(holder);
        }else {
            holder = (ViewHolder) convertView.getTag();
        }

        final DiveProfile diverObjectTask = mTasks.get(position);

        holder.diverAttended.setChecked(diverObjectTask.isDiverAttended());
        holder.diveTime.setText(diverObjectTask.getDiveTime());

        holder.diverAttended.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                CheckBox cb = (CheckBox) v.findViewById(R.id.diver_attended_checkbox);

                if (cb.isChecked()) {
                    itemChecked.set(position, true);
                    // do some operations here
                } else if (!cb.isChecked()) {
                   itemChecked.set(position, false);
                   // do some operations here
                }
             }
        });
        holder.diverAttended.setChecked(itemChecked.get(position)); // this will Check or Uncheck the

        holder.diveTime.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

                String txt = setDiveTimeDialog();
                holder.diveTime.setText(txt);
                mTasks.get(position).setCurrentText(txt); //add the setter to the current item's position
            }
        });
        holder.diveTime.setText(diverObjectTask.getCurrentText());

        return convertView;
    }

    static class ViewHolder {
        CheckBox diverAttended;
        EditText diveTime;
        EditText depth;
    }

    private String setDiveTimeDialog() {

        //final String[] items = finItems;
        final String[] items = getContext().getResources().getStringArray(R.array.certification_level_items);

        // Create list dialog with required parameters - context, title, and our array of items to fill the list.
        CustomListDialog.Builder builder = new CustomListDialog.Builder(getContext(), "Dive Time", items);

        // Now again we can use some extra methods on the builder to customise it more.
        builder.titleAlignment(BaseDialog.Alignment.LEFT);
        builder.itemAlignment(BaseDialog.Alignment.LEFT);
        builder.titleColor(getContext().getResources().getColor(R.color.primary_color));


        // Now we can build our dialog.
        CustomListDialog customListDialog = builder.build();

        // Finally we can show it.
        customListDialog.show();

        customListDialog.setListClickListener(new CustomListDialog.ListClickListener() {
            @Override
            public void onListItemSelected(int i, String[] strings, String s) {

                result = s;

            }
        });

        return result;
    }
}

【问题讨论】:

  • 你在哪里设置了editText的文本??

标签: android listview android-listview android-edittext


【解决方案1】:

你应该这样做:

final DiveProfile diverObjectTask = mTasks.get(position);
holder.diveTime.setText(diverObjectTask.getDiveTie());
//also set your CheckBox value

这些值变为空是因为您没有在 getView 中设置它(getView 在列表滚动时自动被调用)

更新

看你的问题,我认为最简单的方法是在DiveProfile 类中创建新变量,例如boolean isSelectedString currentText

之后,就不需要使用像itemChecked 这样的单独列表了。您可以getset 当前项目的值。

getter使用示例:

holder.diverAttended.setChecked(mTasks.get(position).getSelected()); // getSelected is isSelected getter method

然后在你的holder.diverAttendedonClick中调用setSelectedsetter of isSelected

EditTextsetter 的示例:

    holder.diveTime.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {

            String txt = setDiveTimeDialog();
            holder.diveTime.setText(txt);
            mTasks.get(position).setcurrentText(txt); //add the setter to the current item's position
        }
    });

并在getView 中调用getCurrentText()

【讨论】:

  • 我已经有了,但它不起作用。所以我决定在 StackOverflow 中简化这里的代码。
  • @user2033242 请发布您的代码,它不起作用,它是您案例中最重要的代码:) 提示:确保您同时拥有if-else 的条件
  • @user2033242 你的holder.diveTime.setText 中没有getView,你只有onClick 中的那个。你应该两者都有
  • 我在 onClick 中有它,因为会打开一个对话框并且用户选择其中一个选项。如果我在 onClick 之外执行holder.diveTime.setText(setDiveTimeDialog());,则将为所有项目打开对话框。如果我只是做holder.diveTime.setText(diverObjectTask.getDiveTime()); - 它什么也没做。
  • 不,非常感谢您帮助我完成这件事。我所做的是将setDiveTimeDialog() 的全部内容复制/粘贴到onClick 方法中,并强制diveTime.setText(txt); 等到选择完成。它工作得很好:)
【解决方案2】:

您的 Viewholder 变量必须在您的 getView 中,最好是您在 if(convertView) 之前声明的第一个变量。在外部缓存 ViewHolder 会导致不可预知的行为。

ConvertView 是返回的视图,因此您必须设置对转换视图所做的任何更改。

【讨论】:

  • 好的,我根据您的建议编辑了我的代码,但在这种情况下仍然无法正常工作。
  • 在您的 onClick 中,您创建一个新的 CheckBox,用它做一些事情,然后永远不要将它添加到您的转换视图,它会加载旧的。您应该只使用从 getTag() 检索到的那个,然后对 convertView 的复选框进行操作。
  • 你应该看看youtube.com/watch?v=wDBM6wVEO70,因为我不知道你对适配器的工作原理了解多少。
猜你喜欢
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
相关资源
最近更新 更多