编辑Listview自定义适配器中的文本滚动时丢失其位置? - c# - Xamarin.Android

时间:2016-10-28 10:52:45

标签: c# android listview xamarin xamarin.android

当我们在第1行输入值时,当我们滚动到第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;



    //}
}
}

当我们在第1行输入值时,当我们滚动到第6行时,第1行中输入的值将显示在第6行中。请参阅以下代码和建议。

1 个答案:

答案 0 :(得分:0)

根据经验,在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)将为false表示第6行(或使用循环视图的任何其他调用)的标记属性不会更新,并且您实际上使用的是脏值。

然后您尝试将Tag属性用作位置,但如果视图已被回收,则忘记此标记已经很脏了

int pos = (int)holder.namenmn.Tag;

        holder.comsevin.TextChanged += (sender, e) =>
        {
            abc[pos].Value = holder.comsevin.Text;
        };

由于您可以访问此方法调用中的位置,因此您应该直接使用它

从Java Code geeks看一下这个guide,即使它是用Java编写的,你也可以看到旧的ViewHolder / ListView模式的良好实现。

希望这有帮助