Bizzare поведение NotifyDataSetChanged () Xamarin.Android - PullRequest
0 голосов
/ 01 сентября 2018

Я работаю над приложением, которое просит пользователя предоставить фотографии для предметов.

Мой главный объект следующий

public class PickedObject
{
    int ID { get; set; }
    int Name{ get; set; }
    bool HasPhotos { get; set; }
}

И у меня есть еще одна таблица для фотографий, так как один элемент может иметь несколько фотографий.

Что происходит, так это то, что в моем адаптере я создал вид рециркулятора, так что если у элемента есть изображения, перед ним должна быть видимая кнопка ImageButton.

Вот мой шаблон строки

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="8">
        <TextView
            android:id="@+id/lblItemName"
            android:layout_width="0dp"
            android:layout_weight="6"
            android:layout_marginTop="5dp"
            android:layout_marginLeft="10dp"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:text="" />
        <ImageButton
            android:layout_weight="1"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:adjustViewBounds="true"
            android:scaleType="fitCenter"
            android:layout_marginTop="5dp"
            android:background="@android:color/transparent"
            android:padding="5dp"
            android:src="@drawable/rowcamera"
            android:id="@+id/btnCamera" />
        <ImageButton
            android:layout_weight="1"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:adjustViewBounds="true"
            android:scaleType="fitCenter"
            android:layout_marginTop="5dp"
            android:background="@android:color/transparent"
            android:padding="5dp"
            android:src="@drawable/rowpicture"
            android:id="@+id/btnPicture" />     
</LinearLayout>

В моем адаптере я использую следующее в GetView(int position, View convertView, ViewGroup parent)

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        ItemViewHolder holder = null;
        PickedObject item = _items[position];
        View view = convertView;

        try
        { 
            if (view != null)
                holder = (ItemViewHolder)view.Tag; //Holder

            if(holder == null)
            {
                holder = new ItemViewHolder();
                view = _context.LayoutInflater.Inflate(Resource.Layout.ItemRow, null);
                holder.ItemName = view.FindViewById<TextView>(Resource.Id.lblItemName);

                holder.CameraButton = view.FindViewById<ImageButton>(Resource.Id.btnCamera);
                holder.CameraButton.Tag = item.ID;   
                holder.PictureButton = view.FindViewById<ImageButton>(Resource.Id.btnPicture);
                holder.PictureButton.Tag = item.ID;                    

                CameraClickListener cameraListener = new CameraClickListener(_context, this); 
                cameraListener.CameraClickEvent += CameraClickedEvent;
                holder.CameraButton.SetOnClickListener(cameraListener);
                ImageClickListener imageClickListener = new ImageClickListener(_context);
                imageClickListener.ImageClickEvent += ImageClickedEvent;
                holder.PictureButton.SetOnClickListener(imageClickListener);                                        
                view.Tag = holder;
            }

            holder.ItemName.Text = item.Name;               
            holder.CameraButton.Visibility = ViewStates.Visible;

            if (item.HasPhotos)
            {
                holder.PictureButton.Visibility = ViewStates.Invisible;
            }
            else
            {
                holder.PictureButton.Visibility = ViewStates.Visible;
            }
        }
        catch(Exception ex)
        {
            Log.Error("Item adapter", ex.Message);
        }
        return view;
    }

Теперь в моей MainActivity я назвал два действия (для результата). Одним из них является действие камеры, которое запускает камеру и сохраняет фотографию. Другое действие - это действие типа галереи, созданное в рамках проекта.

Деятельность по результату называется следующим образом:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    int itemId = CameraApp.ID; // Camera App is a static object to hold data
    if (requestCode == General.CAMERA_ACTIVITY) // Camera activity code 110
    {
        CompleteCameraActivity(resultCode, data); // Save picture into gallery and update db
    }
    if(requestCode == General.GALLERY_ACTIVITY) // Gallery activity code 113
    {
        CompleteGalleryActivity(resultCode, data);
    }

    SectionFragment frag = (SectionFragment)sectionsAdapter.GetItem(viewPager.CurrentItem);
    int sectionId = frag.Section.ID;        
    frag.Adapter.SetPicture(questionId, dataAccess.HasPictures(itemId));        
}

Метод SetPicture в адаптере выглядит следующим образом:

public void SetPicture(int id, bool hasPics)
{
    Item itm = _items.SingleOrDefault(a => a.ID == id);
    if (itm != null)
        _items.SingleOrDefault(a => a.ID == id).HasPhotos = hasPics;

    this.NotifyDataSetChanged();        
}

Приложение работает нормально, когда оно зависит от активности камеры. Он обновляет запись, а также видна кнопка изображения. Проблема возникает, когда MainActivity получает контроль над GalleryActivity. Когда я удаляю все изображения в галерее, выполняется метод SetPicture, который устанавливает для свойства HasPhotos значение false. Но часть NotifyDataSetChanged адаптера не работает (когда я тестирую ее в отладчике, метод GetView не запускается для адаптера).

Так что получается, что мой ListView остается в состоянии, когда даже если у элемента нет фотографий, кнопка ImageButton (для изображений) все еще доступна. Может кто-нибудь, пожалуйста, дайте мне знать, что я делаю неправильно?

EDIT

Я заметил, что если я прокручиваю список один раз и возвращаюсь к элементу, кнопка ImageButton становится невидимой, это означает, что она работает, но почему она не работает в StartActivityForResult?

...