如何在自定义游标适配器中保留edittext值

时间:2014-10-09 18:58:51

标签: android listview android-cursoradapter android-viewholder

在同一主题上应用堆栈溢出的几乎所有答案后,我找不到解决问题的方法。 我的问题是我有一个列表视图,其中包含每行中的问题和编辑文本。但是当我在编辑文本更改中滚动列表视图数据或者它可能发生时,它会出现在其他编辑文本中。 即如果我在滚动后的第一个editext中写了一些东西,可能会发生在第二行或第三行的edittext中。

我甚至尝试过cursoradapter类的一些东西。

请帮帮我们。

import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;

import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;


public class TestViewAdapter extends CursorAdapter
{
    protected Cursor cursor;
    protected Context context;
    protected Resources res;
    protected Random random;
    protected LayoutInflater inflater;
    protected Map<Integer, String>myinputs;
    protected int mRowIDColumn;

    public TestViewAdapter(Context context, Cursor c)
    {
        super(context, c);
        this.cursor = c;
        this.context = context;
        this.res = this.context.getResources();
        this.random = new Random();
        boolean cursorPresent = c != null;
        mRowIDColumn = cursorPresent ? this.cursor.getColumnIndexOrThrow("_id") : -1;
        this.inflater = (LayoutInflater) this.context.getSystemService(this.context.LAYOUT_INFLATER_SERVICE);
        myinputs = new HashMap<>();
    }

    private static class Viewholder
    {
        TextView question;
        TextView answer;
        EditText useranswer;
        String que = "" , randomStr ="";
    }

    @Override
    public View newView(Context context, Cursor c, ViewGroup parent)
    {
        View rowlayout = this.inflater.inflate(R.layout.testlist_row, null);
        final Viewholder viewHolder;
        String [] meaningArray = new String[] {"synonyms", "antonyms"};

        viewHolder = new Viewholder();

        // Set view for each row
        viewHolder.question = (TextView) rowlayout.findViewById(R.id.tv_test_question);
        viewHolder.answer = (TextView) rowlayout.findViewById(R.id.tv_test_answer);
        viewHolder.useranswer = (EditText) rowlayout.findViewById(R.id.et_test_useranswer);
        viewHolder.que = this.res.getString(R.string.popup_question); //get value from string.xml 

        //viewHolder.randomStr  = meaningArray[this.random.nextInt(meaningArray.length)];
        viewHolder.useranswer.clearFocus();
        rowlayout.setTag(viewHolder);

        return rowlayout;
    }

    @Override
    public int getCount() {
        return cursor.getCount();
    }

    @Override
    public long getItemId(int position) {
        if (cursor != null) {
            if (cursor.moveToPosition(position)) {
                return cursor.getLong(mRowIDColumn);
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    @Override
    public void bindView(View view, Context context, Cursor c)
    {
        final Viewholder viewHolder = (Viewholder) view.getTag();

        final int rowPosition = (int) getItemId(c.getPosition());

        String synonyms = "" , antonyms = "" , word = "",text = "" ,ans = "";

        word = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1)));
        synonyms = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(2)));
        antonyms = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(3)));

        if ( !synonyms.isEmpty())
        {
            text = String.format(viewHolder.que, "synonyms", word.toLowerCase());
            ans = synonyms;
        }
        else if( !antonyms.isEmpty())
        {
            text = String.format(viewHolder.que, "antonyms", word.toLowerCase());
            ans = antonyms;
        }

        viewHolder.question.setText(text);
        viewHolder.answer.setText(ans);

        viewHolder.useranswer.addTextChangedListener(new TextWatcher() {
            @Override
            public void afterTextChanged(Editable s) {}

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

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count)
            {
                if (s.toString().length() > 0) {
                    Log.d("TestViewAdapterb", "pos -" + rowPosition + "," + s.toString());
                    myinputs.put(rowPosition , s.toString());
                }
            }
        });

        String v = myinputs.get(rowPosition);
        viewHolder.useranswer.setText(v == "" ? "" : v);

    }
}

我找到了方法,下面是我保存用户输入的更新代码。 希望它对某些人有所帮助。

public class TestViewAdapter extends CursorAdapter
{
    protected Cursor cursor;
    protected Context context;
    protected Resources res;
    protected Random random;
    protected LayoutInflater inflater;
    protected ArrayList<HashMap<String,String>> resultList;
    protected int mRowIDColumn;


    public TestViewAdapter(Context context, Cursor c)
    {
        super(context, c);
        this.cursor = c;
        this.context = context;
        this.res = this.context.getResources();
        this.random = new Random();
        boolean cursorPresent = c != null;
        mRowIDColumn = cursorPresent ? this.cursor.getColumnIndexOrThrow("_id") : -1;
        this.inflater = (LayoutInflater) this.context.getSystemService(this.context.LAYOUT_INFLATER_SERVICE);
        resultList = new ArrayList<HashMap<String,String>>();

        if(c != null && c.getCount() > 0)
        {
            c.moveToFirst();

            for (int i=0;i<c.getCount();i++)
            {
                HashMap<String,String> row = new HashMap<String,String>();
                row.put("userans","");
                resultList.add(row);
            }
        }
    }

    private static class Viewholder
    {
        TextView question;
        TextView answer;
        EditText useranswer;
        String randomStr ="";
    }

    public ArrayList<HashMap<String,String>> getUserInputResult()
    {
        return resultList;
    }

    @Override
    public View newView(Context context, Cursor c, ViewGroup parent)
    {
        View rowlayout = this.inflater.inflate(R.layout.testlist_row, null);
        final Viewholder viewHolder;
        String [] meaningArray = new String[] {"synonyms", "antonyms"};

        viewHolder = new Viewholder();

        // Set view for each row
        viewHolder.question = (TextView) rowlayout.findViewById(R.id.tv_test_question);
        viewHolder.answer = (TextView) rowlayout.findViewById(R.id.tv_test_answer);
        viewHolder.useranswer = (EditText) rowlayout.findViewById(R.id.et_test_useranswer);

        viewHolder.randomStr  = meaningArray[this.random.nextInt(meaningArray.length)];
        viewHolder.useranswer.clearFocus();
        rowlayout.setTag(viewHolder);

        return rowlayout;
    }

    @Override
    public int getCount() {
        return cursor.getCount();
    }

    @Override
    public long getItemId(int position) {
        if (cursor != null) {
            if (cursor.moveToPosition(position)) {
                return cursor.getLong(mRowIDColumn);
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    @Override
    public void bindView(View view, Context context, Cursor c)
    {
        final Viewholder viewHolder = (Viewholder) view.getTag();
        final int rowPosition = (int) getItemId(cursor.getPosition());
        final int rowId = cursor.getInt(cursor.getColumnIndex(cursor.getColumnName(0)));

        boolean isBoth = false, isSyno = false , isAnto = false, isQuestionset = false;

        String que = "";
        String synonyms = "";
        String antonyms = "";
        String word = "";
        String text = "";
        String ans = "";

        que = this.res.getString(R.string.popup_question);
        word = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(1)));
        synonyms = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(2)));
        antonyms = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(3)));

        if (!synonyms.isEmpty() && !antonyms.isEmpty())
        {
            isBoth = true;
            isSyno = true;
            isAnto = true;
        }
        else if (!synonyms.isEmpty())
        {
            isSyno = true;
        }
        else if (!antonyms.isEmpty())
        {
            isAnto = true;
        }

        if (isBoth)
        {
            if(viewHolder.randomStr.equals("synonyms"))
            {
                text = String.format(que, "synonyms", word.toLowerCase());
                ans = synonyms;
            }
            else
            {
                text = String.format(que, "antonyms", word.toLowerCase());
                ans = antonyms;
            }
        }
        else if (isSyno)
        {
            if (viewHolder.randomStr.equals("synonyms"))
            {
                text = String.format(que, "synonyms", word.toLowerCase());
                ans = synonyms;
                isQuestionset = true;
            }
            else if (isAnto)
            {
                text = String.format(que, "antonyms", word.toLowerCase());
                ans = antonyms;
                isQuestionset = true;
            }

            if (!isQuestionset)
            {
                text = String.format(que, "synonyms", word.toLowerCase());
                ans = synonyms;
                isQuestionset = true;
            }

        }
        else if (isAnto)
        {
            text = String.format(que, "antonyms", word.toLowerCase());
            ans = antonyms;
        }

        viewHolder.question.setText(text);
        viewHolder.answer.setText(ans);

        HashMap<String,String> row = resultList.get(c.getPosition());
        row.put("preans",ans);

        viewHolder.useranswer.setId(cursor.getPosition());
        viewHolder.useranswer.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus)
            {
                if (!hasFocus)
                {
                    if (((EditText)v).getText().toString().length() > 0) {
                        Log.d("TestViewAdapterb", "pos -" + rowPosition + "," + ((EditText)v).getText().toString().trim());
                        HashMap<String,String> row = resultList.get(v.getId());
                        row.put("userans",((EditText)v).getText().toString().trim());
                    }
                }

            }
        });

        viewHolder.useranswer.setText(row.get("userans"));
    }
}

还有一件事

  

机器人:descendantFocusability = “beforeDescendants”

当用户点击列表视图的项目时,这将允许子视图获得焦点。当用户滚动列表视图时存储值我使用了包含hashmap对象的arraylist。我学到的第二件事是,使用'=='来代替它的同意字符串使用isEmpty方法或包含方法。

1 个答案:

答案 0 :(得分:0)

我想问题就在于这一行:

text = String.format(viewHolder.que, "synonyms", word.toLowerCase());

我这样说的原因是因为您引用了ViewHolder来获取文本的值。由于ViewHolder会循环使用,因此文本的值也会回收。

尝试直接从光标获取文本的值,而无需ViewHolder的干预。