How to preserve edittext value in custom cursor adapter

非 Y 不嫁゛ 提交于 2019-12-13 03:00:29

问题


After applying almost all answers from stack overflow on same topic but i can not find solution for my problem. my problem is i have a list view which contain a question and a edit text in each row. but when i scroll list view data in edit text change or it may happen it comes in other edit text. i.e if i write some thing in 1st editext after scroll it may happen it is in 2nd or 3rd row edittext.

Some of the thing i have even tried from cursoradapter class but still.

Please help me guys.

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);

    }
}

I got the way and below one is my updated code for preserving user input. hope it will be helpful to some body.

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"));
    }
}

One more thing add

android:descendantFocusability="beforeDescendants"

This will allow child view to get focus when user clicks on item of the list view.To store value when user scroll the listview i have used arraylist which holds hashmap object. second thing i learned is that never comparee string using '==' in place of it use isEmpty method or contains method.


回答1:


I imagine the issue lies in this line:

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

The reason I say this is because you're referencing the ViewHolder to get the value of the text. Since the ViewHolder recycles, the value of your text will recycle too.

Try getting the value of the text directly from the cursor without intervention from the ViewHolder.



来源:https://stackoverflow.com/questions/26286006/how-to-preserve-edittext-value-in-custom-cursor-adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!