Listview повторяет данные в последующих строках - PullRequest
0 голосов
/ 31 августа 2018

У меня есть макет с некоторыми кнопками и списком. Одна из кнопок добавляет запись в базу данных SQLite. Другая кнопка отображает записи в виде списка - возможно, 1, 2 или более, скажем, 3, в зависимости от того, сколько раз я нажимаю первую кнопку. Однако, когда я нажимаю кнопку, чтобы отобразить записи в виде списка и прокручиваю вниз список, те же записи появляются в нижних строках, которые обычно разделяются пустыми строками, поэтому строка 6 снова начинает список. Когда я прокручиваю вниз и снова вверх, больше нежелательных записей появляются в нижних строках. В каждой заполненной строке есть «правильная» запись, слишком много одинаковых. Когда я нажимаю кнопку, которая повторно отображает записи в виде списка, представление возвращается к нормальному состоянию, пока я снова не прокручиваю вниз. Если я уменьшу высоту представления списка, то повторы начинаются со строки 5, а не со строки 6. Код прилагается. Во-первых, кнопка в MainActivity, которая заполняет список:

        //ShowRecordsInListView
    Button button5 = FindViewById<Button>(Resource.Id.button5_ID);
    button5.Click += delegate
    {

        try
        {
            //Set up the db connection:
            var db = new SQLiteConnection(dbPath);

            //Set up a table:
            db.CreateTable<FieldNamesInTable2>();

            //Get these items from the database and populate the array:
            FieldNamesInTable2[] myRecords = new FieldNamesInTable2[30];
            var table = db.Table<FieldNamesInTable2>();

            int count = 0;
            foreach (var item in table)
            {
                myRecords[count] = item;
                count++;
            }

            //Get ListView:
            var lv = FindViewById<ListView>(Resource.Id.recordsListView_ID);
            lv.Adapter = new HomeScreenAdaptor(this, myRecords);

        }
        catch (Exception e)
        {
            //System.Diagnostics.Debug.WriteLine(e);
            Toast.MakeText(this, e.Message, ToastLength.Long).Show();
        }

    };

Обратите внимание на строку: lv.Adapter = новый HomeScreenAdaptor (this, myRecords);

Верхняя часть кода от MainActivity:

    namespace Database2.Droid
{
    [Activity(Label = "Database2", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true)]
    public class MainActivity : AppCompatActivity
    {       

        //Path string for database file:
        string dbPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "dbDatabase.db3");

        protected override void OnCreate(Bundle savedInstanceState)
        {

            base.OnCreate(savedInstanceState);

            SetContentView(Resource.Layout.Database2Layout);

... и т.д.

Представление списка фактически заполняется из HomeScreenAdaptor.cs, как показано ниже:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace Database2.Droid
{

    class HomeScreenAdaptor : BaseAdapter<FieldNamesInTable2>
    //ListView: - this one uses HomeScreenAdapter but has a bug in it which is either it crashes if there are fewer than 6 items, or it repeats
    //randomly with spaces between repeats of the same data lower in the listview.
    {
        FieldNamesInTable2[] myRecords;
        Activity context;

        public HomeScreenAdaptor(Activity context, FieldNamesInTable2[] records) : base()
        {
            this.myRecords = records;
            this.context = context;
        }

        //You need to override 4 attributes:
        public override long GetItemId(int position)
        {
            return position;

        }

        public override FieldNamesInTable2 this[int position]
        {
            get
            {
                return myRecords[position];
            }
        }

        public override int Count
        {
            get
            {
                return myRecords.Length;
            }
        }

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

            //Reuse a row if one becomes available.
            View view = convertView;
            try
            {
                if (view == null)
                {
                    //See Xamarin documentation 'Built-in Row Views' will show you the different types of views - simple, selectable, checkboxes, highlightable, with pictures etc.
                    view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
                }
                //Weird alert!! - Text1 exists
                view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = myRecords[position].ToString();
                //Text1 is used by the listview to populate each row.

            }
            catch (Exception)
            {
                //System.Diagnostics.Debug.WriteLine(e);
                return view;
            }
            return view;

        }
    }
}

Области попытки перехвата предотвращают сбой, если нет записей или менее 6 записей - это может быть крайне важно!

Любые исправления для проблемы с повторяющимися строками приветствуются.

1 Ответ

0 голосов
/ 08 сентября 2018

попробуйте это ... я изменил ваш метод GetView ()

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

        //Reuse a row if one becomes available.
        View view = convertView;
        ViewHolder viewholder;
            if (view == null)
            {
                //See Xamarin documentation 'Built-in Row Views' will show you the different types of views - simple, selectable, checkboxes, highlightable, with pictures etc.
                view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);

            viewholder=new ViewHolder();
            //Weird alert!! - Text1 exists

            viewholder.text1=(TextView)view.findviewbyid(Android.Resource.Id.Text1);

            //Text1 is used by the listview to populate each row.

            view.setTag(viewholder)
           }else{
                viewholder=(ViewHolder)view.getTag();
           }
           viewholder.text1.setText(myRecords[position]);
        return view;

    }
    private class ViewHolder{
         TextView text1;
    }
...