在列表视图自定义适配器中编辑文本在滚动时失去其位置?——Xamarin.Android
本文关键字:失去 位置 Android Xamarin 滚动 视图 列表 自定义 适配器 编辑 文本 | 更新日期: 2023-09-27 18:15:33
当我们在第一行输入value时,当我们滚动到第6行时,在第1行输入的值会出现在第6行。请参阅以下代码和建议。
namespace Kites
{
public class Marks
{
// add any if you need more
public string StudentName { get; set; }
public string MarksScored { get; set; }
}
public class TEXTCHECK
{
public int POS { get; set; }
public string Value { get; set; }
}
public class MarksListViewAdapter : BaseAdapter<Marks>
{
private List<Marks> mstuduentmarks;
private List<TEXTCHECK> abc = new List<TEXTCHECK>();
private Context mcontext;
public MarksListViewAdapter (Context context, List<Marks> stud)
{
mstuduentmarks = stud;
mcontext = context;
}
public override int Count
{
get
{
return mstuduentmarks.Count;
// return mattendence.Count;
}
}
public override long GetItemId (int position)
{
return position;
}
public override Marks this[int position]
{
get
{
return mstuduentmarks [position];
// return mattendence [position];
}
}
class ViewHolder : Java.Lang.Object
{
public EditText comsevin;
public TextView namenmn;
}
public override View GetView (int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
View view = convertView;
if (view == null) // otherwise create a new one
{
view = LayoutInflater.From(mcontext).Inflate(Resource.Layout.listview_Marks, null, false);
holder = new ViewHolder();
holder.comsevin = view.FindViewById<EditText>(Resource.Id.editTextTeacherMarks);
holder.namenmn = view.FindViewById<TextView>(Resource.Id.textStudentNameTeacherMarks);
holder.namenmn.Tag = position;
view.Tag = holder;
}
else
{
holder = (ViewHolder)view.Tag;
}
holder.namenmn.Text = mstuduentmarks[position].StudentName;
int pos = (int)holder.namenmn.Tag;
holder.comsevin.TextChanged += (sender, e) =>
{
abc[pos].Value = holder.comsevin.Text;
};
//TextView txtStudent =
//txtStudent.Text = mstuduentmarks[position].StudentName;
//txtMarks.FocusChange += (object sender, View.FocusChangeEventArgs e) =>
//{
// //txtMarks.RequestFocusFromTouch ();
// mstuduentmarks[position].MarksScored = txtMarks.Text;
//};
holder.comsevin.BeforeTextChanged += (sender, e) =>
{
abc.Add(new TEXTCHECK { POS = position, Value = mstuduentmarks[position].MarksScored });
};
holder.comsevin.AfterTextChanged += (sender, e) =>
{
int a = abc[pos].POS;
mstuduentmarks[pos].MarksScored = abc[pos].Value;
};
//txtMarks.Tag = position;
//txtMarks.TextChanged += TxtMarks_TextChanged;
return view;
}
//void TxtMarks_TextChanged (object sender, Android.Text.TextChangedEventArgs e)
//{
// EditText txtMarks = (EditText)sender;
// //var position = (int)txtMarks.Tag;
//}
}
}
当我们在第一行输入value时,当我们滚动到第6行时,在第1行输入的值会出现在第6行。请参阅以下代码和建议
作为一个经验法则,当遇到列表不反映数据集(例如经历项目重复)在listview/recyclerview这意味着你要么使用脏视图,以前使用过,然后不正确地重新绑定,或者只是使用错误的位置在绑定
我知道你哪里搞错了:
if (view == null) // otherwise create a new one
{
view = LayoutInflater.From(mcontext).Inflate(Resource.Layout.listview_Marks, null, false);
holder = new ViewHolder();
holder.comsevin = view.FindViewById<EditText>(Resource.Id.editTextTeacherMarks);
holder.namenmn = view.FindViewById<TextView>(Resource.Id.textStudentNameTeacherMarks);
holder.namenmn.Tag = position;//<------------here!!!
view.Tag = holder;
}
TLDR不要这样保存位置
发生了什么:你的视图的这个实例被listView重用,这意味着有时(很多次)if (view == null)将是假的,这意味着标签属性将不会被更新为第6行(或任何其他调用将使用回收视图),你实际上是使用一个脏值。
你然后试图使用Tag属性作为位置,但忘记这个标签已经脏了,如果视图被回收
int pos = (int)holder.namenmn.Tag;
holder.comsevin.TextChanged += (sender, e) =>
{
abc[pos].Value = holder.comsevin.Text;
};
因为你可以在这个方法调用中访问位置,所以你应该直接使用它
看一看这个来自Java代码极客的指南,尽管它是用Java编写的,你还是可以看到一个很好的老式ViewHolder/ListView模式的实现。
希望能有所帮助