如何使 EditText 值在可滚动列表视图中持久化

how to make the EditText value persistent in a scrollable listview

我有一个由 TextView、EditText 和 Checkbox 组成的列表视图。我想让 edittext 的状态持久化,这样当我更改文本时 在 edittext 内,然后向上或向下滚动列表视图 added/written 进入 edittext 的文本不应更改,必须保持原样

我设法使复选框持久化,但我不知道如何使编辑文本状态持久化。

请查看下面发布的 getView() 方法 请让我知道如何解决这个问题

getView

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    View view = null;

    if (convertView == null) {
        LayoutInflater layoutinflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        view = layoutinflater.inflate(R.layout.model, null);

        final ViewHolder holder = new ViewHolder();

        holder.tv = (TextView) view.findViewById(R.id.tv);
        holder.cb = (CheckBox) view.findViewById(R.id.cb);
        holder.et = (EditText) view.findViewById(R.id.et);

        holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub

                ItemDesign element = (ItemDesign) holder.cb.getTag();
                element.setChecked(buttonView.isChecked());
            }
        });

        view.setTag(holder);

        holder.cb.setTag(designList.get(position));//checkbox

        //edittext
        ItemDesign element = (ItemDesign) holder.et.getTag();
        if (element != null) {
            element.setEtTxt(holder.et.getText().toString());
        }
        holder.et.setTag(designList.get(position));

        holder.tv.setTag(designList.get(position));//textview

    } else {
        view = convertView;

        ((ViewHolder)view.getTag()).et.setTag(designList.get(position));//edittext
        ((ViewHolder)view.getTag()).tv.setTag(designList.get(position));//textview
        ((ViewHolder)view.getTag()).cb.setTag(designList.get(position));//checkbox
    }
    ViewHolder holder = (ViewHolder) view.getTag();

    holder.tv.setText(designList.get(position).getTxt()); //textview
    holder.cb.setChecked(designList.get(position).isChecked());//checkbox

    //edittext
    String etTxt = holder.et.getText().toString();
    designList.get(position).setEtTxt(etTxt);
    holder.et.setText(designList.get(position).getEtTxt());

    return view;
}
private class ViewHolder {
    TextView tv;
    CheckBox cb;
    EditText et;
}

您应该向您的编辑文本添加一个 TextWatcher 并使用它来跟踪输入到文本视图的文本。

holder.et.setTag(designList.get(position));//edittext    
holder.et.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) {
            ItemDesign element = (ItemDesign) holder.cb.getTag();
            element.setEditTextValue(s.toString())
        }

如果我没理解错的话,您需要在 EditText 中注册 TextWatcher 并在每次更改其中的文本时保存字符串值。所以你需要更新你的部分代码 from:

String etTxt = holder.et.getText().toString();
designList.get(position).setEtTxt(etTxt);
holder.et.setText(designList.get(position).getEtTxt());

(对不起,我不知道你在designList中有什么时间的元素,但是让它成为,例如,输入Item, 你可以通过你的类型而不是它):

final Item designItem = designList.get(position);
holder.et.setText(designItem.getEtTxt());
holder.et.addTextChangedListener(new TextWatcher() {
    @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 editable) {
        designItem.setEtTxt(editable.toString);
    }
});

但是要小心。这个解决方案还没有工作,因为你已经注册了新的和新的观察者但没有清除旧的。在这种情况下,我没有完美的解决方案,因为 EditText 没有 clearTextChangedListeners() 这样的东西。但是你可以通过引入你自己的 EditText (copied from here):

来解决它
public class ExtendedEditText extends EditText {
    private ArrayList<TextWatcher> mListeners = null;

    public ExtendedEditText(Context ctx) {
        super(ctx);
    }

    public ExtendedEditText(Context ctx, AttributeSet attrs) {
        super(ctx, attrs);
    }

    public ExtendedEditText(Context ctx, AttributeSet attrs, int defStyle) {
        super(ctx, attrs, defStyle);
    }

    @Override
    public void addTextChangedListener(TextWatcher watcher) {
        if (mListeners == null) {
            mListeners = new ArrayList<TextWatcher>();
        }
        mListeners.add(watcher);

        super.addTextChangedListener(watcher);
    }

    @Override
    public void removeTextChangedListener(TextWatcher watcher) {
        if (mListeners != null) {
            int i = mListeners.indexOf(watcher);
            if (i >= 0) {
                mListeners.remove(i);
            }
        }

        super.removeTextChangedListener(watcher);
    }

    public void clearTextChangedListeners() {
        if (mListeners != null) {
            for (TextWatcher watcher : mListeners) {
                super.removeTextChangedListener(watcher);
            }

            mListeners.clear();
            mListeners = null;
        }
    }
}

之后最终解决方案将如下所示:

final Item designItem = designList.get(position);
holder.et.clearTextChangedListeners();
holder.et.setText(designItem.getEtTxt());
holder.et.addTextChangedListener(new TextWatcher() {
    @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 editable) {
        designItem.setEtTxt(editable.toString);
    }
});

其中 et 将是 ExtendedEditText 类型而不是 EditText