自定义ListView在屏幕上滚动然后返回时会更改其数据

时间:2016-08-30 20:16:55

标签: android listview xamarin

所以我有一个为Xamarin-Android制作的自定义ListView,它从员工轮班列表中获取数据并将其转换为行。有些数据正在被错误地报告(显示他们没有的转移),并且当滚动数据时会定期更改。

本质上,我向适配器传递一个Employees列表,每个Employees都有一个包含开始和结束时间的List类型。适配器循环遍历每个班次,使用开关将任何一天路由到正确的TextViews,然后粘贴数据。由于某种原因,某些行的数据显示不正确,但其他行也没问题。当您单击该行(我有一个单独的视图来编辑数据)时,数据会正确反映出它应该是什么。我试图逐步找出正在发生的事情,但是当它踩到它时显示行正确返回。

在数据显示不正确的情况下,当向上和向下滚动时,当一行离开屏幕时,它有时会返回不同的数据。

以下是适配器代码:

using System;
using System.Collections.Generic;
using Android.Content;
using Android.Views;
using Android.Widget;

namespace MaydSchedulerApp
{
    class ScheduleAdapter : BaseAdapter<EmployeeScheduleWrapper>
    {
        private List<EmployeeScheduleWrapper> mItems;
        private Context mContext;
        private bool sun = false, mon = false, tue = false, wed = false, thu = false, fri = false, sat = false;

        public ScheduleAdapter(Context context, List<EmployeeScheduleWrapper> items)
        {
            mItems = items;
            mContext = context;
        }

        public override int Count
        {
            get
            {
                return mItems.Count;
            }
        }

        public override long GetItemId(int position)
        {
            return position;
        }

        public override EmployeeScheduleWrapper this[int position]
        {
            get
            {
                return mItems[position];
            }
        }

        public override View GetView(int position, View convertView, ViewGroup parent)
        {
            View row = convertView;

            if (row == null)
            {
                row = LayoutInflater.From(mContext).Inflate(Resource.Layout.ScheduleListView, null, false);
            }

            TextView txtName = row.FindViewById<TextView>(Resource.Id.txtScheduleName);
            txtName.Text = mItems[position].lName + ", " + mItems[position].fName;

            TextView txtPosition = row.FindViewById<TextView>(Resource.Id.txtSchedulePosition);
            txtPosition.Text = CoreSystem.GetPositionName(mItems[position].position);

            TextView txtSunday = row.FindViewById<TextView>(Resource.Id.txtSun);
            TextView txtMonday = row.FindViewById<TextView>(Resource.Id.txtMon);
            TextView txtTuesday = row.FindViewById<TextView>(Resource.Id.txtTue);
            TextView txtWednesday = row.FindViewById<TextView>(Resource.Id.txtWed);
            TextView txtThursday = row.FindViewById<TextView>(Resource.Id.txtThu);
            TextView txtFriday = row.FindViewById<TextView>(Resource.Id.txtFri);
            TextView txtSaturday = row.FindViewById<TextView>(Resource.Id.txtSat);
            for (int i = 0; i < mItems[position].shiftList.Count; i++)
            {
                switch (mItems[position].shiftList[i].date)
                {
                    case DayOfWeek.Sunday:
                        txtSunday.Text = mItems[position].shiftList[i].startShift.ToString() + "00 - " + mItems[position].shiftList[i].endShift.ToString() + "00";
                        sun = true;
                        break;
                    case DayOfWeek.Monday:
                        txtMonday.Text = mItems[position].shiftList[i].startShift.ToString() + "00 - " + mItems[position].shiftList[i].endShift.ToString() + "00";
                        mon = true;
                        break;
                    case DayOfWeek.Tuesday:
                        txtTuesday.Text = mItems[position].shiftList[i].startShift.ToString() + "00 - " + mItems[position].shiftList[i].endShift.ToString() + "00";
                        tue = true;
                        break;
                    case DayOfWeek.Wednesday:
                        txtWednesday.Text = mItems[position].shiftList[i].startShift.ToString() + "00 - " + mItems[position].shiftList[i].endShift.ToString() + "00";
                        wed = true;
                        break;
                    case DayOfWeek.Thursday:
                        txtThursday.Text = mItems[position].shiftList[i].startShift.ToString() + "00 - " + mItems[position].shiftList[i].endShift.ToString() + "00";
                        thu = true;
                        break;
                    case DayOfWeek.Friday:
                        txtFriday.Text = mItems[position].shiftList[i].startShift.ToString() + "00 - " + mItems[position].shiftList[i].endShift.ToString() + "00";
                        fri = true;
                        break;
                    case DayOfWeek.Saturday:
                        txtSaturday.Text = mItems[position].shiftList[i].startShift.ToString() + "00 - " + mItems[position].shiftList[i].endShift.ToString() + "00";
                        sat = true;
                        break;
                }
            }
            if (!sun)
                txtSunday.Text = "Off";
            if (!mon)
                txtMonday.Text = "Off";
            if (!tue)
                txtTuesday.Text = "Off";
            if (!wed)
                txtWednesday.Text = "Off";
            if (!thu)
                txtThursday.Text = "Off";
            if (!fri)
                txtFriday.Text = "Off";
            if (!sat)
                txtSaturday.Text = "Off";
            return row;
        }
    }
}

这是EmployeeScheduleWrapper的代码

using System;
using System.Collections;
using System.Collections.Generic;

namespace MaydSchedulerApp
{
    public class EmployeeScheduleWrapper
    {
        public string lName, fName;
        public int employee;
        public int position;
        public int hourTarget;
        public int skill;//This is to minimize callbacks to the main emp later
        public int scheduledHours;
        //The availability is copied onto this so that it can be modified without effecting the set availability in the employee type
        public Availability availability = new Availability();
        public bool availabilityModified = false;
        public List<Shift> shiftList = new List<Shift>();

        public EmployeeScheduleWrapper() { }

        public EmployeeScheduleWrapper(Employee emp)
        {
            lName = emp.empLastName;
            fName = emp.empFirstName;
            employee = emp.empID;
            position = emp.position;
            skill = emp.skillLevel;
            hourTarget = emp.hourTarget;
            scheduledHours = 0;
            //availability = emp.availability;//Dont init this unless its changed and needs to be saved
            availabilityModified = false;
        }

        public void SetTempAvailability(Availability avail)//TODO add check for when avail last changed to warn user if availability is no longer useful
        {
            availability = avail;
            availabilityModified = true;
        }

        public void PermanentAvailabilityChange(Availability avail)
        {
            availability = avail;
            availabilityModified = false;//since were using the permanent change
            EmployeeStorage.GetEmployee(employee).availability = avail;
        }

        public Availability GetEntireAvail()
        {
            if (availabilityModified)
                return availability;
            else
            {//This fixes the direct memory interaction when modifying temp availability
                availability = new Availability(EmployeeStorage.GetEmployee(employee).availability);
                return availability;
            }
        }

        public bool GetAvailability(int day)
        {
            if (availabilityModified)
            {
                switch (day)
                {
                    case 0:
                        return availability.sunday.available;
                    case 1:
                        return availability.monday.available;
                    case 2:
                        return availability.tuesday.available;
                    case 3:
                        return availability.wednesday.available;
                    case 4:
                        return availability.thursday.available;
                    case 5:
                        return availability.friday.available;
                    case 6:
                        return availability.saturday.available;
                    default:
                        Console.WriteLine("Invalid case chosen! :: EmployeeManagement/Employee.cs :: GetAvailability(int day): Invalid Value for Day Thrown! :: Returning false!");
                        break;
                }
                return false;
            }
            else
            {
                return EmployeeStorage.GetEmployee(employee).GetAvailability(day);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您需要将视图重置为空数据。

也就是说,列表视图将重新使用convertview来优化内存。在此期间,列表视图将返回先前使用的包含先前数据的转换视图。所以你需要重置getView()

中的数据

那是:

            txtSunday.Text = "";

            txtMonday.Text = "";

            txtTuesday.Text = "";

            txtWednesday.Text = "";

            txtThursday.Text = "";

            txtFriday.Text = "";

            txtSaturday.Text = "";
切换案例陈述后的