ListView ItemClick事件未触发自定义ListView适配器

时间:2019-06-10 20:17:54

标签: c# android listview xamarin.android android-listadapter

因此,当我从“自定义ListView”中单击项目时,主活动中的ItemClick事件没有触发。我查看了其他答案,并认为这两个图像按钮将使焦点移开,因此我尝试了不同的方式将两个按钮的可聚焦性都设置为false,甚至在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 :(得分:0)

您可以尝试通过以下代码设置属性:

//对于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">

答案 1 :(得分:0)

本身并不是一个答案,但这是一种解决方法,可以解决我的问题,这可能对其他人有用。

所以我创建了一个只包含一个int变量的类,并在MainActivity中实例化了它(可以将其声明为int,但是我幻想有一个类可以保存数据,因为对象是通过引用传递的)

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

在MainActivity中

PosHolder _pos = new PosHolder();

我将我选择的函数作为lambda表达式和_pos传递给了我的适配器构造器

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

在我的适配器类中,我创建一个动作,并将单击侦听器添加到我的根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();
            };

我可能离最佳实践还很远,但是它对我有用,并且可以解决我的问题。

希望有帮助。