在ListView中的EditText没有它回收输入 [英] EditText in ListView without it recycling input

查看:283
本文介绍了在ListView中的EditText没有它回收输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

还是新的android和甚至更多的自定义光标适配器,所以我有麻烦了解如何防止我的列表视图回收视图,以防止输入一个编辑文本显示在另一个滚动时。我已经看到其他帖子说更改convertview的名称,但如何做,我正在绘制一个空白。我希望这里的人能够根据我到目前为止写的代码给出更多的细节或示例。

Still new to android and even more to custom cursor adapter so I'm having trouble understanding how to prevent my listview from recycling views to prevent input from one edittext to show up in another when scrolled. I've seen on other post saying to change the name of convertview but how to do that I'm drawing a blank. I was hoping someone here would be able to give more details or example of how to do based of what code I've wrote so far.

public class editview extends ListActivity {
    private dbadapter mydbhelper;
    private PopupWindow pw;
    public static int editCount;
    public static ListView listView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mydbhelper = new dbadapter(this);
        mydbhelper.open();


        View footer = getLayoutInflater().inflate(R.layout.footer_layout, null);
        ListView listView = getListView();
        listView.addFooterView(footer);
        showResults();
        }

    //Populate view
    private void showResults (){
        Cursor cursor = mydbhelper.getUserWord();
        startManagingCursor(cursor);
        String[] from = new String[] {dbadapter.KEY_USERWORD};
         int[] to = new int[] {R.id.textType};
         ItemAdapter adapter = new ItemAdapter(this, R.layout.edit_row, cursor,
                        from, to);
            adapter.notifyDataSetChanged();
            this.setListAdapter(adapter);
            editCount = adapter.getCount();

    }


            //footer button
            public void onClick(View footer){
                    final MediaPlayer editClickSound = MediaPlayer.create(this, R.raw.button50);
                    editClickSound.start();
                    startActivity(new Intent("wanted.pro.madlibs.OUTPUT"));

                }

//custom cursor adapter
class ItemAdapter extends SimpleCursorAdapter {
    private LayoutInflater mInflater;
    private Cursor cursor;


    public ItemAdapter(Context context, int layout, Cursor cursor, String[] from,
            int[] to) {
        super(context, layout, cursor, from, to);
        this.cursor = cursor;
        mInflater = LayoutInflater.from(context);

    }


    static class ViewHolder {
        protected TextView text;
        protected EditText edittext;

    }

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


        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.edit_row, null);


             holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.textType);
            holder.edittext = (EditText) convertView.findViewById(R.id.editText);



            convertView.setTag(holder);

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

        }
        cursor.moveToPosition(position);
        int label_index = cursor.getColumnIndex("userword"); 
        String label = cursor.getString(label_index);

        holder.text.setText(label);

        return convertView;

    }

}

更改为

class ItemAdapter extends SimpleCursorAdapter {
    private LayoutInflater mInflater;
    private Cursor cursor;
    Map<Integer, String> inputValues = new HashMap<Integer, String>();
    public View getView(final int position, View convertView, ViewGroup parent) {
        ....

        ViewHolder holder;
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.edit_row, null);


             holder = new ViewHolder();
            holder.text = (TextView) convertView.findViewById(R.id.textType);
            holder.edittext = (EditText) convertView.findViewById(R.id.editText);


            convertView.setTag(holder);

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

        }
        cursor.moveToPosition(position);
        int label_index = cursor.getColumnIndex("userword"); 
        String label = cursor.getString(label_index);

        holder.text.setText(label);
        String oldText =  inputValues.get(position);
        holder.edittext.setText(oldText == null ? "" : oldText); 
        holder.edittext.addTextChangedListener(new TextWatcher(){
            public void afterTextChanged(Editable editable) {
                inputValues.put(position, editable.toString());
            }

但是它在所有edittext都有数据后被回收。使用holder.edittext.setText(oldText)

but it is recycling after all edittext have data. Tried using holder.edittext.setText(oldText) but same effect.

推荐答案

首先,你真的不想阻止列表视图回收它的视图。视图回收是一个巨大的优化。对于很多关于列表的很好的信息,请参阅google IO talk: http://www.youtube.com/watch?v=wDBM6wVEO70

First of all, you really don't want to prevent a list view from recycling its views. View recycling is a huge optimization. For a lot of really good info on lists, see the google IO talk: http://www.youtube.com/watch?v=wDBM6wVEO70

话虽如此,你已经正确地识别了你的问题:你的列表中的EditTexts比你做的项目少得多。当你滚动列表时,这些EditTexts被循环使用,所以你看到相同的输入一遍又一遍。

That being said, you've correctly identified your problem: You have far fewer EditTexts than you do items in your list. As the you scroll through the list those EditTexts are recycled so you see the same input over and over again.

基本上你需要做的是在一些数据结构中保存你的EditTexts的输入(一个HashMap,如果他们只会编辑几个值,也许一个List,如果他们将改变大多数值,要么工作)将位置映射到输入。你可以通过在getView中添加一个textChangedListener到你的编辑文本中来实现:

Basically what you need to do is save the input for your EditTexts in some datastructure (a HashMap if they will only edit a few values, maybe a List if they will be changing most of the values, either would work) that maps the position to the input. You can do this by adding a textChangedListener to your edit texts in getView:

@Override
public View getView(final int position, View convertView, ViewGroup parent){
    ...
    cursor.moveToPosition(position);
    int label_index = cursor.getColumnIndex("userword");
    String label = cursor.getString(label_index);

    holder.text.setText(label);

    //clear whatever text was there from some other position
    //and set it to whatever text the user edited for the current 
    //position if available
    String oldText = yourMapOfPositionsToValues.get(position);
    holder.setText(oldText == null ? "" : oldText); 

    //every time the user adds/removes a character from the edit text, save 
    //the current value of the edit text to retrieve later
    holder.edittext.addTextChangedListener(new TextWatcher(){
        @Override
        public void afterTextChanged(Editable editable) {
            yourMapOfPositionsToValues.put(position, editable.toString());
        }
        ....
    };

    return convertView;
}

每当您的用户完成编辑时,您可以通过您的数据结构运行这些值。

Whenever your user is done editing, you can run through your datastructure and do whatever with those values.

编辑:

我改变了onTextChanged到afterTextChanged,因为我之前使用过,我知道它的工作原理。记住,afterTextChanged被调用每次LETTER更改,而不仅仅是在用户完成输入一个单词后,如果用户类型dogafterTextChanged将被调用三次,先用'd',然后用'do',然后用'dog'。

I changed onTextChanged to afterTextChanged because I've used that before and I know it works. Keep in mind that afterTextChanged is called every time a LETTER changes, not just after the user finishes typing a word. If the user types "dog" afterTextChanged will be called three times, first with 'd', then with 'do', then with 'dog'.

HashMap很简单:映射yourMapOfPositionsToValues = new HashMap();

A HashMap is simple: Map yourMapOfPositionsToValues = new HashMap();

添加或更新项目:yourMap.put(position,someText);
获取一个项目:yourMap.get(position);

to add or update an item: yourMap.put(position, someText); to fetch an item: yourMap.get(position);

如果hashmap没有意义,花一些时间研究它们。它们是一个非常重要的数据结构。

if hashmaps don't make sense, spend some time researching them. They are an incredibly important data structure.

您的TextWatcher实现不正确。您的数据结构不应属于单个视图,而应属于活动或适配器。您似乎觉得仓位不稳定,因为您的列表由每个视图所有。位置本身是稳定的,因为除非基础数据改变,否则光标将在每次对相同位置返回相同的数据。但是,编辑文本用于多个不同的位置。

Your TextWatcher implementation is incorrect. Your data structure should not belong to a single view, but rather the activity or your adapter. It appears to you that positions aren't stable because your List is owned by each view. The positions themselves are stable in that unless the underlying data changes the cursor will return the same data every time for the same position. However, the edit text is used for multiple different positions.

创建一个hashmap作为上面在适配器的构造函数中演示的实例变量。然后添加刚才我写的TextWatcher,不需要一个命名类,匿名更简单。你的代码应该工作。

Create a hashmap as an instance variable I demonstrated above in the constructor of your adapter. Then add exactly the TextWatcher I wrote originally, no need for a named class, anonymous is simpler. Your code should work.

这篇关于在ListView中的EditText没有它回收输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆