【问题标题】:Custom ListView is changing its data when it is scrolled off screen then back自定义 ListView 在滚动离开屏幕然后返回时正在更改其数据
【发布时间】:2016-08-31 04:27:56
【问题描述】:

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

基本上,我向适配器传递了一个员工列表,每个员工都有一个包含开始和结束时间的列表类型。适配器循环遍历每个班次,使用开关将它所在的任何一天路由到正确的 TextView,然后粘贴数据。由于某种原因,某些行的数据显示不正确,但其他行很好。当您单击该行时(我有一个单独的视图来编辑数据),数据会正确地反映它应该是什么。我试图单步执行并弄清楚发生了什么,但是在单步执行时显示行正在正确返回。

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

这是适配器代码:

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

【问题讨论】:

    标签: android listview xamarin


    【解决方案1】:

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

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

    即:

                txtSunday.Text = "";
    
                txtMonday.Text = "";
    
                txtTuesday.Text = "";
    
                txtWednesday.Text = "";
    
                txtThursday.Text = "";
    
                txtFriday.Text = "";
    
                txtSaturday.Text = "";
    

    在switch case语句之后

    【讨论】:

    • 就是这样,非常感谢。在谷歌上搜索时,我尝试了尽可能多的措辞,但没有什么能解释如何解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-27
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 2021-02-06
    • 2011-10-24
    相关资源
    最近更新 更多