我正在尝试设置商店页面可点击。我正在使用自定义列表视图,该视图显示有关所点击项目的 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);
}
}
答案 0 :(得分: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");
}
您可以尽可能避免代理或匿名lambdas,因为您无法获取对原始方法的引用并将其取消挂钩。 (不用更多代码保留对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;
}
}
}