【问题标题】:Android ListView clickable with AlertDialog使用 AlertDialog 可点击的 Android ListView
【发布时间】:2016-08-26 03:54:40
【问题描述】:

我正在尝试使商店页面可点击。我正在使用自定义列表视图,该列表视图显示关于所单击项目的 AlertDialog

我的目标是,当我点击按钮时,打开一个允许购买的警告对话框。

当我向下滚动所有列表时,显示了许多 alertDialog,而不是只有 一个

我的自定义适配器扩展自 BaseAdapter,我的 getView() 方法如下所示:

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

    if(row == null)
    {
        var inflater = context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater;
        row = inflater.Inflate(Resource.Layout.SingleRowStorePage, parent, false);

        holder = new ViewHolder(row);
        row.Tag = holder;

    } else
    {
        holder = (ViewHolder)row.Tag;
    }           

    //SET DATA
    holder.Qtd.Text = "Qtd:" + quantities[position];
    holder.Stock.Text = "Stock: " + shops[position].Stock.ToString();
    holder.Name.Text = shops[position].Name;
    holder.Creditos.Text = shops[position].Price.ToString() + " créditos ";

    //CLICK
    holder.Image.Click += delegate
    {
        Android.Support.V4.App.FragmentTransaction trans = manager.BeginTransaction();
        DialogShop dialog = new DialogShop(shops[position]);
        dialog.Show(trans, "image");
    };

    //confirm shop?
    holder.Comprar.Click += delegate
    {
        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        alert.SetTitle("Confirmar compra? item " + shops[position].Name + " com valor: " + quantities[position]);
        alert.SetMessage("Lorem ipsum dolor sit amet, consectetuer adipiscing elit.");
        alert.SetPositiveButton("Ok", (senderAlert, args) =>
        {
            //Toast.MakeText(context, "Ok!", ToastLength.Short).Show();
        });

        alert.SetNegativeButton("Cancelar", (senderAlert, args) =>
        {
            //Toast.MakeText(context, "Cancelar!", ToastLength.Short).Show();
        });

        Dialog dialog = alert.Create();
        dialog.Show();
        dialog.Dismiss();
    };

    return row;
}

我的 ViewHolder:

private class ViewHolder : Java.Lang.Object
{
    public ImageView Image { get; set; }
    public Button Qtd { get; set; }
    public TextView Stock { get; set; }
    public TextView Name { get; set; }
    public TextView Creditos { get; set; }
    public Button Comprar { get; set; }

    public ViewHolder(View view)
    {
        Image = view.FindViewById<ImageView>(Resource.Id.singleRowStore);
        Qtd = view.FindViewById<Button>(Resource.Id.buttonComprar);
        Stock = view.FindViewById<TextView>(Resource.Id.stockStore);
        Name = view.FindViewById<TextView>(Resource.Id.nomeStore);
        Creditos = view.FindViewById<TextView>(Resource.Id.creditosStore);
        Comprar = view.FindViewById<Button>(Resource.Id.comprarStore);
    }
}

【问题讨论】:

  • 您想在滚动或单击 btn 时显示警报对话框?
  • 当按钮被点击时

标签: c# android listview xamarin


【解决方案1】:

问题是您正在使用委托来连接您的事件,并且由于可以回收单元格,因此每次重复使用单元格时都会附加额外的点击事件。

在你的适配器中而不是这个:

holder.Image.Click += delegate
{
    Android.Support.V4.App.FragmentTransaction trans = manager.BeginTransaction();
    DialogShop dialog = new DialogShop(shops[position]);
    dialog.Show(trans, "image");
};

改为对所有处理程序执行此操作:

holder.Image.Click -= ImageClicked;
holder.Image.Click += ImageClicked;

private void ImageClicked (object sender, EventArgs e)
{
    Android.Support.V4.App.FragmentTransaction trans = manager.BeginTransaction();
    DialogShop dialog = new DialogShop(shops[position]);
    dialog.Show(trans, "image");
}

您应该尽可能避免使用委托或匿名 lambda,因为您无法取回对原始方法的引用并取消挂钩。 (不使用更多代码保留对 lamdba 的引用)。

private class ViewHolder : Java.Lang.Object
        {
            //public EventHandler<>
            public ImageView Image { get; set; }
            public Button Qtd { get; set; }
            public TextView Stock { get; set; }
            public TextView Name { get; set; }
            public TextView Creditos { get; set; }
            public Button Comprar { get; set; }

            //New Event Handler
            public EventHandler<ImageClickedEventArgs> ImageClicked;

            public ViewHolder(View view)
            {
                Image = view.FindViewById<ImageView>(Resource.Id.singleRowStore);
                Qtd = view.FindViewById<Button>(Resource.Id.buttonComprar);
                Stock = view.FindViewById<TextView>(Resource.Id.stockStore);
                Name = view.FindViewById<TextView>(Resource.Id.nomeStore);
                Creditos = view.FindViewById<TextView>(Resource.Id.creditosStore);
                Comprar = view.FindViewById<Button>(Resource.Id.comprarStore);

                Image.Click += Image_Click;
            }

            void Image_Click(object sender, EventArgs e)
            {
                ImageClicked?.Invoke(sender, new ImageClickedEventArgs(this));
            }

            public class ImageClickedEventArgs : EventArgs
            {
                public ViewHolder ViewHolder { get; private set; }

                public ImageClickedEventArgs(ViewHolder viewHolder) : base()
                {
                    ViewHolder = viewHolder;
                }
            }
        }

【讨论】:

  • 感谢您的回答。但是如何访问 ImageClicked 方法中的位置?
  • 这是一个与您原始帖子中的问题不同的问题。有多种模式可以处理这个问题。一种方法是使用您需要的参数创建自定义 EventArgs。然后,您将订阅它而不是 ImageClick。如果您需要更多帮助,请告诉我,我可以为您提供所有详细信息。
  • 对不起,但不起作用。 ImageClicked 方法被多次调用,和之前的方法一样。
  • 您确定在连接 ImageClicked 之前将其解开吗? ImageClicked -= YourImageClickedHandler; ImageClicked += YourImageClickedHandler;
猜你喜欢
  • 2015-05-09
  • 2017-09-27
  • 2016-02-18
  • 2016-09-10
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多