当前位置: 首页 > 知识库问答 >
问题:

正在RecyclerView中保存EditText内容

宁侯林
2023-03-14

我有一个带有EditText的列表项,我不知道会有多少项。当我在EditText中输入一些文本,然后向下滚动回收站视图时,我遇到了一个问题,当我再次向上滚动后,我的第一个 中没有文本。

我想知道我应该写什么,在哪里写代码,这样当用户在EditText中键入或完成键入(我想用一个TextWatcher>来完成)时,文本会保存到一个文件中(我将它保存在外部存储的.txt文件中)

我应该在活动的onCreate方法中,还是在适配器类或其他地方这样做?

下面是一些代码

 public class MainActivity extends Activity {

    RecyclerView mRecyclerView;
    MyAdapter mAdapter;
    String[] mDataSet= new String[20];
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // generating text for editText Views
        for (int i = 0; i<=19; i++){
        mDataSet[i]= "EditText n: "+i;

    }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mAdapter = new MyAdapter(mDataSet);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setHasFixedSize(true);
    }
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

private String[] mDataset;


public static class ViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public EditText mEditText;

    public ViewHolder(View v) {
        super(v);

        mEditText = (EditText) v.findViewById(R.id.list_item_edittext);
    }
}

public MyAdapter(String[] myDataset) {
    mDataset = myDataset;
}

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                 int viewType) {

    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.list_item, parent, false);

    ViewHolder vh = new ViewHolder(v);
    return vh;
}

@Override
public void onBindViewHolder(ViewHolder holder,  final int position) {
    holder.mEditText.setText(mDataset[position]);

    //without this addtextChangedListener my code works fine ovbiusly
    // not saving the content of the edit Text when scrolled
    // If i add this code then when i scroll all textView that go of screen
    // and than come back in have messed up content
    holder.mEditText.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start,
                                  int before, int count) {
           //setting data to array, when changed
           // this is a semplified example in the actual app i save the text
           // in  a .txt in the external storage
           mDataset[position] = s.toString();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start,
                                      int count, int after) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

}

@Override
public int getItemCount() {
    return mDataset.length;
}

如果没有这个“addtextChangedListener ”,我的代码工作得很好,显然不会在滚动时保存编辑文本的内容。如果我添加了这段代码,当我滚动所有的editText视图时,这些视图都离开了屏幕,然后又回来,这些视图弄乱了内容。

共有3个答案

林俊英
2023-03-14

我实现了@dkarmazi解决方案,但它对我没有帮助。所以,我走得更远了,有一个真正有效的解决方案。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private String[] mDataset;

    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_edittext, parent, false);
        // pass MyCustomEditTextListener to viewholder in onCreateViewHolder
        // so that we don't have to do this expensive allocation in onBindViewHolder
        ViewHolder vh = new ViewHolder(v, new MyCustomEditTextListener());

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        // update MyCustomEditTextListener every time we bind a new item
        // so that it knows what item in mDataset to update
        holder.myCustomEditTextListener.updatePosition(holder.getAdapterPosition());
        holder.mEditText.setText(mDataset[holder.getAdapterPosition()]);
    }

    @Override
    public int getItemCount() {
        return mDataset.length;
    }

    @Override
    public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
        ((ViewHolder) holder).enableTextWatcher();
    }

    @Override
    public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
        ((ViewHolder) holder).disableTextWatcher();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public EditText mEditText;
        public MyCustomEditTextListener myCustomEditTextListener;

        public ViewHolder(View v, MyCustomEditTextListener myCustomEditTextListener) {
            super(v);

            this.mEditText = (EditText) v.findViewById(R.id.editText);
            this.myCustomEditTextListener = myCustomEditTextListener;
        }
        
        void enableTextWatcher() {
            mEditText.addTextChangedListener(myCustomEditTextListener);
        }

        void disableTextWatcher() {
            mEditText.removeTextChangedListener(myCustomEditTextListener);
        }
    }

    // we make TextWatcher to be aware of the position it currently works with
    // this way, once a new item is attached in onBindViewHolder, it will
    // update current position MyCustomEditTextListener, reference to which is kept by ViewHolder
    private class MyCustomEditTextListener implements TextWatcher {
        private int position;

        public void updatePosition(int position) {
            this.position = position;
        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            // no op
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            mDataset[position] = charSequence.toString();
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // no op
        }
    }
}

主要问题是应用的TextWatcher在物品回收过程中继续工作。

我试过在回收之前禁用它,但是没有任何“beforeRecycle”事件方法。所以我使用了onViewDetachedFromWindow方法,效果很好。

冯元徽
2023-03-14

我也有同样的问题,我添加了下面一行,它似乎已经修复了我这边的问题。

mRecyclerview.setItemViewCacheSize(mDataset.size());

希望这能解决你这边的问题。

危飞跃
2023-03-14

您的解决方案的主要问题是在onBindViewHolder中分配和分配TextWatcher,这是一项昂贵的操作,在快速滚动期间会产生延迟,并且似乎还会干扰确定mAdapter中要更新的位置。

在onCreateViewHolder中进行所有操作是更可取的选择。以下是经过测试的完整工作解决方案:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private String[] mDataset;

    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_edittext, parent, false);
        // pass MyCustomEditTextListener to viewholder in onCreateViewHolder
        // so that we don't have to do this expensive allocation in onBindViewHolder
        ViewHolder vh = new ViewHolder(v, new MyCustomEditTextListener());

        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        // update MyCustomEditTextListener every time we bind a new item
        // so that it knows what item in mDataset to update
        holder.myCustomEditTextListener.updatePosition(holder.getAdapterPosition());
        holder.mEditText.setText(mDataset[holder.getAdapterPosition()]);
    }

    @Override
    public int getItemCount() {
        return mDataset.length;
    }


    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public EditText mEditText;
        public MyCustomEditTextListener myCustomEditTextListener;

        public ViewHolder(View v, MyCustomEditTextListener myCustomEditTextListener) {
            super(v);

            this.mEditText = (EditText) v.findViewById(R.id.editText);
            this.myCustomEditTextListener = myCustomEditTextListener;
            this.mEditText.addTextChangedListener(myCustomEditTextListener);
        }
    }

    // we make TextWatcher to be aware of the position it currently works with
    // this way, once a new item is attached in onBindViewHolder, it will
    // update current position MyCustomEditTextListener, reference to which is kept by ViewHolder
    private class MyCustomEditTextListener implements TextWatcher {
        private int position;

        public void updatePosition(int position) {
            this.position = position;
        }

        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            // no op
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            mDataset[position] = charSequence.toString();
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // no op
        }
    }
}
 类似资料:
  • 问题内容: 在我的项目中,我必须向用户显示一个ListView,它基本上包含EditText。 就像问卷一样,当他回答问题时,他可以下去回答下一个问题。(然后返回) 我不知道为什么,但是用户进入ListView,内容未保存,并显示一些特殊值,如其他EditText。我没有找到纠正该行为的方法,这真的很着急。 基本上,我做了一个TextWatcher,将数据注册到数据库中,还注册到了包含所有值的临时

  • 我有一个编辑文本视图,可以在编辑文本中的提要上发表评论。当我在编辑文本中放入大量文本并出现滚动条时,我无法滚动编辑文本的文本内容<当我想在编辑文本中滚动时,代码>循环视图(code>Recyclerview)会向上滚动。我怎样才能解决这个问题。请提出建议。

  • 本文向大家介绍Android实现EditText内容保存为Bitmap的方法,包括了Android实现EditText内容保存为Bitmap的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Android实现EditText内容保存为Bitmap的方法。分享给大家供大家参考,具体如下: 主要代码如下: 更多关于Android控件相关内容感兴趣的读者可查看本站专题:《Android控件用

  • 问题内容: 我试图动态地保存具有不同颜色的编辑文本,但是当我通过将其转换为HTML形式进行保存时,它只会将文本保存为一种颜色,而不是我选择的颜色。 这是Textchanged,str是可扩展文本。 问题答案: 在文本更改后尝试此操作,它将解决您的问题。

  • 我在回收站被击中查看, 这里的名称和平衡字段来自两个不同的数组。我需要的是,这里每一行都有一个EditText字段。我需要访问每一行上的每个EditText。并从中获取值...总计显示在Total text View上。可能吗?我试了很多次。我没有得到它。 我在这里上课。 主要活动 } 数据持有者 } 适配器 }

  • 问题内容: 嗨,我正在尝试将EditText小部件值保存在手机/平板电脑的内部存储器中,以便应用程序关闭或活动停止时可以自动检索它们。所有这些都可以使用保存按钮来完成。(窗口小部件的值由用户输入)。 问题答案: 您应该使用共享首选项,共享首选项用于在需要访问数据时将其存储在本地应用程序中。使用此链接https://www.journaldev.com/9412/android- shared-pr