简体   繁体   中英

Android Xamarin Button inside a ListView

I want to create a ListView of objects in one of my activities, each row should have TextView and 3 Buttons. When I click on the buttons I don't want to handle them on the ListView ' Adapter, I want to use them inside my Activity.

Is there any way to declare the buttons in my activity and set OnClickListener() for them? In addition I need to get the button position in the ListView . In other words I want to do something like that in my activity:

button = listView.FindViewById<Button>(Resource.Id.button);
button.SetOnClickListener(this);

and in public void OnClick(View v) do something like:

if (v == button)
{
    int positionInList = /* something */;
    //...
}

The easiest way of doing it would be by adding the click event in the GetView method:

public View GetView( int position, View convertView, ViewGroup parent) 
{
    .
    .
    .
    .
    yourButton.Click+= (sender,eventArgs) =>
    {
       // Your event 
    }
});

Good luck

Feel free to get back if you have any queries.

You can use delegate as well. Following are the code sample

Activity will have listview or recyclerview. Method which needs to be handled in the activity, will be passed as action to Adapter.

public void CreateListView()
{
 testAdapter = new TestAdapter(vm.ForageSamples.ToList(), OnClick);
 recyclerView.SetAdapter(testAdapter);
}

private void OnClick(EventArgs e)
{
 //your logic
}

Action (delegate) will be passed to adapter. That action will be passed to ViewHolder.

 public class TestAdapter : RecyclerView.Adapter
    {
        List<Sample> forageTests;
        private readonly Action<EventArgs> activityClick;

        public TestAdapter(List<Sample> tests, Action<EventArgs> activityClick)
        {
            this.forageTests = tests;
            this.activityClick = activityClick;
        }

        public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
        {
            var layout = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.template_foragetests, parent, false);
            return new TestViewHolder(layout, activityClick);
        }
    }

And viewholder will have the button click event. The action which was passed from adapter will be invoked in the click event. Hence, button click event will be propagated to activity.

 public class TestViewHolder : RecyclerView.ViewHolder
    {
        private Action<EventArgs> activityClick;
        private Button addButton;

        public TestViewHolder (View itemView, Action<EventArgs> activityClick) : base(itemView)
        {
             this.activityClick = activityClick;
             addButton = itemView.FindViewById<Button>(Resource.Id.addbutton);
            addButton.Click += OnClick;
        }
     
        void OnClick(object sender, EventArgs e)
        {
            activityClick(e);
        }
    }

if your are not using viewholder then, this code will be added in adapter itself.

I end up doing something similar to FreakyAli's answer, but changed it so I can implement my click event in my activity and not in the adapter:

if (!button.HasOnClickListeners)
{
    button.Click += delegate {
        ((MyActivity)context).MyButtonClickFunction(position);
    };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM