Событие ListView ItemClick не запускается для пользовательского адаптера ListView - PullRequest
0 голосов
/ 10 июня 2019

Таким образом, мое событие ItemClick в моей основной активности не запускается, когда я нажимаю на элементы в моем Custom ListView. Я посмотрел на другие ответы и подумал, что две кнопки «Изображение» отвлекают внимание, поэтому я пробовал разные способы установить фокусировку на «ложь» для обеих кнопок и даже пробовал это в ImageView, но пока это не работает , Может кто-нибудь сказать мне, почему? Вот мой код.

Наценка за каждый предмет.

Layout1.axml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#FFDAFF7F"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:id="@+id/SpiceRowItem">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        >
        <ImageView
            android:id="@+id/Thumbnail"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:background="#000000"
         />
        <LinearLayout
            android:id="@+id/Text"
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="10dip">
            <TextView
                android:text="Allspice"
                android:id="@+id/Heading"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#FF7F3300"
                android:textSize="20dip"
                android:textStyle="italic"
         />
            <TextView
                android:text="Warm, sweet"
                android:id="@+id/Flavour"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textSize="14dip"
                android:textColor="#FF267F00"
         />
        </LinearLayout>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/ImageWrap"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_alignParentRight="true">
        <ImageButton
            android:text="Cupboard"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:id="@+id/AddToCupboard" />
        <ImageButton
            android:text="List"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:id="@+id/AddToList" />
    </LinearLayout>


</RelativeLayout>

И метод GetView из моего пользовательского адаптера (я использую делегаты, чтобы я мог инкапсулировать переменную "position"):

SpiceListAdapter.cs

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

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

            ImageView Thumbnail = row.FindViewById<ImageView>(Resource.Id.Thumbnail);
            TextView Heading = row.FindViewById<TextView>(Resource.Id.Heading);
            TextView Flavour = row.FindViewById<TextView>(Resource.Id.Flavour);
            ImageButton AddToCupboard = row.FindViewById<ImageButton>(Resource.Id.AddToCupboard);
            ImageButton AddToList = row.FindViewById<ImageButton>(Resource.Id.AddToList);
            RelativeLayout SpiceRowItem = row.FindViewById<RelativeLayout>(Resource.Id.SpiceRowItem);

            //Populates heading and flavour of each row

            Heading.Text = mItems[position].name.ToString();
            Flavour.Text = mItems[position].flavour.ToString();

            //Populate button pictures

            if (mItems[position].cupboard)
            {
                AddToCupboard.SetImageResource(Resource.Drawable.CupboardClosed);
            }
            else
            {
                AddToCupboard.SetImageResource(Resource.Drawable.CupboardOpen);
            }
            if (!mItems[position].list)
            {
                AddToList.SetImageResource(Resource.Drawable.ListEmpty);
            }
            else
            {
                AddToList.SetImageResource(Resource.Drawable.ListFull);
            }

            //Adds Thumbnail picture

            var id = (int)typeof(Resource.Drawable).GetField(mItems[position].picture.ToString()).GetValue(null);
            Thumbnail.SetImageResource(id);

            //Adds onclick event for "Add to cupboard"

            AddToCupboard.Click += delegate
            {
                string RemMessage = "Removed From Cupboard";
                string AddMessage = "Added To Cupboard";
                mItems[position].cupboard = !mItems[position].cupboard;
                if (!mItems[position].cupboard)
                {
                    AddToCupboard.SetImageResource(Resource.Drawable.CupboardOpen);
                    Toast.MakeText(mContext, RemMessage, ToastLength.Short).Show();
                }
                else
                {
                    AddToCupboard.SetImageResource(Resource.Drawable.CupboardClosed);
                    Toast.MakeText(mContext, AddMessage, ToastLength.Short).Show();
                }

            };

            //Adds onclick event for "Add to shopping list"


            AddToList.Click += delegate
            {
                string RemMessage = "Removed From Shopping List";
                string AddMessage = "Added To Shopping List";
                mItems[position].list = !mItems[position].list;
                if (!mItems[position].list)
                {
                    AddToList.SetImageResource(Resource.Drawable.ListEmpty);
                    Toast.MakeText(mContext, RemMessage, ToastLength.Short).Show();
                }
                else
                {
                    AddToList.SetImageResource(Resource.Drawable.ListFull);
                    Toast.MakeText(mContext, AddMessage, ToastLength.Short).Show();
                }
            };
                return row;
          }

И, наконец, его реализация в Main Activity:

MainActivity.cs

//Instantiate Adapters
            SpiceListAdapter _adapter = new SpiceListAdapter(this, spices);
            SpiceListAdapter _CupboardAdapter = new SpiceListAdapter(this, cupboard);
            SpiceListAdapter _ShoppingAdapter = new SpiceListAdapter(this, shoppingList);
            _lv.Adapter = _adapter;

//Click Event handlers
            _lv.ItemClick += _lv_ItemClick;

private void _lv_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
        {
            Console.WriteLine("Poop");
        }

p.s. по какой-то причине я использую глупые консольные строки при тестировании, это просто делает меня вменяемым: D.

Ответы [ 2 ]

0 голосов
/ 12 июня 2019

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

Итак, я создал класс, который содержал единственную переменную int, и создал его в MainActivity (мог просто объявить int, но мне хотелось иметь класс для хранения данных, поскольку объекты передаются по ссылке)

 class PosHolder
    {
        public int pos { get; set; }
    }

А в MainActivity

PosHolder _pos = new PosHolder();

Я передал обе выбранные функции как лямбда-выражение и _pos в конструктор адаптера

SpiceListAdapter _adapter = new SpiceListAdapter(this, spices, () => { MyFunction(); }, _pos);

В моем классе адаптера я создал Action, добавил слушатель щелчка в мой корневой узел макета axml. Это событие click изменяет значение _pos на «position», а затем использует метод click.Invoke () для вызова функции, переданной в конструктор.

//create action
public Action Click { get; set; }
// Adapter Constructor
public SpiceListAdapter(Context context, List<Spice> names, Action click, PosHolder Pos)
        {
            mItems = names;
            mContext = context;
            Click = click;
            mPos = Pos;
            mCupboard = cupboard;
            mShopList = shoppingList;
        }
//Click event
SpiceRowItem.Click += delegate
            {
                mPos.pos = position;
                Click?.Invoke();
            };

Я, вероятно, далек от лучшей практики, но она работает для меня и разобралась с моей проблемой.

Надеюсь, это поможет.

0 голосов
/ 11 июня 2019

Вы можете попробовать установить свойство в коде следующим образом:

// для AddToCupboard

AddToCupboard.Focusable = false;
AddToCupboard.FocusableInTouchMode = false;
AddToCupboard.Clickable = true;
AddToCupboard.Click += delegate
        {
           //....
        };

// для AddToList

AddToList.Focusable = false;
AddToList.FocusableInTouchMode = false;
AddToList.Clickable = true;
AddToList.Click += delegate
        {
           //....
        };

Другой метод:Самый простой способ сделать это - установить для своей корневой группы ViewGroup значение android:descendantFocusability="blocksDescendants", поэтому она заблокирует все элементы управления, на которые она фокусируется.

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFDAFF7F"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:descendantFocusability="blocksDescendants"
android:id="@+id/SpiceRowItem">

...