Обновление пользовательского listviewAdapter - PullRequest
0 голосов
/ 29 апреля 2020

Я хочу добавить новые данные в свой listviewAdapter, я попробовал это сделать, очистив все данные перед этим и уведомив, что теперь есть данные, но они, похоже, не работают. Я следовал Solution (stackoverflow) , но он не работает.

У кого-нибудь есть идеи, почему?

public class ReportsListViewAdapter : BaseAdapter<IMobileReport>, IFilterable
{
    internal List<IMobileReport> originalData;
    internal List<IMobileReport> reports;
    private Context context;
    public override IMobileReport this[int position] => reports[position];

    public ReportsListViewAdapter(Context context, IEnumerable<IMobileReport> reports)
    {
        this.reports = reports.OrderBy(report => report.StudyDate).ToList();
        this.context = context;
        Filter = new ReportsFilter(this);
    }

    public override int Count => this.reports.Count;
    public Filter Filter { get; private set; }
    public override long GetItemId(int position)
    {
        return position;
    }

    public void updateReportsList(List<MobileReport> newlist)
    {
        reports.AddRange(newlist);
        this.NotifyDataSetChanged();
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View row = convertView;
        if(row == null)
        {
            row = LayoutInflater.From(context).Inflate(Resource.Layout.listView_reports_row, null, false);
        }

        var txtName = row.FindViewById<TextView>(Resource.Id.txtName);
        txtName.Text = reports[position].Student.Name;

        var txtFirstName = row.FindViewById<TextView>(Resource.Id.txtFirstName);
        txtFirstName.Text = reports[position].Student.FirstName;

        var txtSource = row.FindViewById<TextView>(Resource.Id.txtSource);
        txtSource.Text = reports[position].Source;
        var txtCritical = row.FindViewById<TextView>(Resource.Id.txtCritical);
        txtSource.Text = reports[position].Critical.ToString();
        return row;

    }
}


protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        reports = new List<IMobileReport>();
        //Init();
        _reportsHubConnector = new ReportsHubConnector();

        #pragma warning disable 4014 // We cannot await this task here because the signature of the inherited method is void
        Task.Factory.StartNew(async () =>
        {
            await _reportsHubConnector.StartConnection();
            await _reportsHubConnector.SendT();

        }, TaskCreationOptions.PreferFairness);
        #pragma warning restore 4014

        Console.WriteLine("HomeActivity: OnCreate");
        SetContentView(Resource.Layout.activity_reports);
        SupportActionBar.SetDisplayShowTitleEnabled(false);
        SupportActionBar.SetDisplayHomeAsUpEnabled(false);
        SupportActionBar.SetDisplayShowHomeEnabled(true);

        WireUpElements();

        listView = FindViewById<ListView>(Resource.Id.reports);
        ReportsListViewAdapter adapter = new ReportsListViewAdapter(this, reports);

        listView.Adapter = adapter;

        searchView = FindViewById<SearchView>(Resource.Id.searchView1);
        searchView.QueryTextChange += this.Filter;

        listView.ItemClick += ItemClicked;

        criticalButton = FindViewById<LinearLayout>(Resource.Id.AuthenticatorButton);
        criticalButton.Click += criticalClicked;

        _reportsHubConnector.ReportsRecieved += (reports) =>
        {
            adapter.updateReportsList(reports);

        };
    }

Когда я медленно отлаживаю, GetView действительно получает может быть, это ключ к пониманию того, почему он не вызывается, когда я не отлаживаюсь или go поверх кода.

This.RunOnUiThread никогда не вызывается, а update -.

 _reportsHubConnector.ReportsRecieved += (tmpReports) =>
 {
       adapter.updateReportsList(tmpReports);
       this.RunOnUiThread(() =>
       {

            criticalButton.SetBackgroundColor(Android.Graphics.Color.Red);
        });
  };

1 Ответ

1 голос
/ 30 апреля 2020

Я попытался сделать это, очистив все данные перед этим и уведомив, что теперь есть данные, но они, похоже, не работают.

Из общего кода, не видя ясного метода, Вы можете добавить reports.Clear(), чтобы проверить, работает ли он.

public void updateReportsList(List<MobileReport> newlist)
{
    reports.Clear();
    reports.AddRange(newlist);
    this.NotifyDataSetChanged();
}

Если не работает, необходимо проверить, добавлен ли newlist правильный формат данных.

===== =================== Обновление =============================

В методе OnCreate, где _reportsHubConnector.ReportsRecieved метод обновления вызова изменяется следующим образом:

_reportsHubConnector.ReportsRecieved += (tmpReports) =>
{
    adapter.updateReportsList(tmpReports);

};

Измените аргумент reports на tmpReports, чтобы избежать смешивания с исходными данными reports.

Следовательно, существует другой распространенный способ обновления данных адаптера:

_reportsHubConnector.ReportsRecieved += (reports) =>
{
    List<IMobileReport> tmp = new List<IMobileReport>();
    tmp =  reports ; // use a tmp list data for updating , not using original list data 
    adapter.updateReportsList(tmp);

};

======================= ==== Обновление =====================================

Из моего примера проекта я нахожу Интересное явление и, возможно, проблема.

Здесь я поделюсь своим пользовательским адаптером HomeScreenAdapter :

public class HomeScreenAdapter : BaseAdapter<TableItem> {
    List<TableItem> items;
    Activity context;
    public HomeScreenAdapter(Activity context, List<TableItem> items)
        : base()
    {
        this.context = context;
        this.items = new List<TableItem>();
        this.items.AddRange(items);
        //this.items = items;
    }
    public override long GetItemId(int position)
    {
        return position;
    }
    public override TableItem this[int position]
    {
        get { return items[position]; }
    }
    public override int Count
    {
        get { return items.Count; }
    }
    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        var item = items[position];

        View view = convertView;
        if (view == null) // no view to re-use, create new
            view = context.LayoutInflater.Inflate(Resource.Layout.CustomView, null);
        view.FindViewById<TextView>(Resource.Id.Text1).Text = item.Heading;
        view.FindViewById<TextView>(Resource.Id.Text2).Text = item.SubHeading+" items";
        view.FindViewById<ImageView>(Resource.Id.Image).SetImageResource(item.ImageResourceId);

        return view;
    }

    public void UpdateListView(List<TableItem> newTableItem)
    {
        items.Clear();
        items.AddRange(newTableItem);
        NotifyDataSetChanged();
    }
}

Вы увидите в Constructor из HomeScree nAdapter , я прокомментировал эту строку кода this.items = items;. Причина, по которой он будет работать:

enter image description here

Однако , если я использую this.items = items; вместо this.items.AddRange(items);, он будет Обновление ничего даже не может ничего показать в ListView.

public HomeScreenAdapter(Activity context, List<TableItem> items)
    : base()
{
    this.context = context;
    this.items = new List<TableItem>();
    //this.items.AddRange(items);
    this.items = items;
}

Эффект:

enter image description here

Возможное причина :

Если здесь используется знак равенства, адрес указателя элементов изменится. Когда данные обновляются, они не могут указывать на исходный источник данных, поэтому обновление не может быть успешным.

Поэтому , здесь Constructor вашего кода можно изменить следующим образом, чтобы проверить, как это происходит. это работает:

public ReportsListViewAdapter(Context context, IEnumerable<IMobileReport> reports)
{
    //this.reports = reports.OrderBy(report => report.StudyDate).ToList();
    this.reports =  new List<IMobileReport>();
    this.reports.AddRange(reports.OrderBy(report => report.StudyDate).ToList());
    this.context = context;
    Filter = new ReportsFilter(this);
}

Связано : Вот примерная ссылка проекта .

...