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.