Sorry, I'm using google translate.
Hello, I am developing an app in xamarin android with visual studio 2017 for taking orders where I send information from a fragment to a List<EN_WishDetalle> to store the selection of items and this is dumped to an adapter to show it in another fragment.
In layout design it has 3 buttons (add quantity/decrease quantity/delete item),
the error lies when removing an item from the listview with sList.RemoveAt(position); NotifyDataSetChanged();
This is deleted and updated in the listview but when I try to execute any of the mentioned buttons again they make a double call (it is as if they were pressed twice and they execute their function twice)
all as a result of the NotifyDataSetChanged();
I have already checked it, however if I close the fragment with backspace (back) and re-enter everything works correctly until I use the delete item button again and we return to the same problem; so I thought of avoiding using it (NotifyDataSetChanged();) and looking for a way to reload the fragment's listview from the adapter without any success. I would like your support or suggestion to take the right path.
adapter:
public override View GetView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
try
{
if (row == null)
{
row = LayoutInflater.From(sContext).Inflate(Resource.Layout.item_Wish, null, false);
}
TextView txtCodigo = row.FindViewById<TextView>(Resource.Id.Codigo);
txtCodigo.Text = sList[position].codigo;
TextView txtArticulo = row.FindViewById<TextView>(Resource.Id.Articulo);
txtArticulo.Text = sList[position].articulo;
EditText txtCantidad = row.FindViewById<EditText>(Resource.Id.Cantidad);
txtCantidad.Text = sList[position].cantidad.ToString();
TextView txtPrecio = row.FindViewById<TextView>(Resource.Id.Precio);
txtPrecio.Text = sList[position].importetotal;
ImageView Art = row.FindViewById<ImageView>(Resource.Id.Image);
Art.SetImageResource(Android.Resource.Color.Transparent);
if (sList[position].imagenproducto == "")
{
Art.SetImageResource(Resource.Drawable.NoDisponible);
}
else
{
Android.Net.Uri myUri = (Android.Net.Uri.Parse(sList[position].imagenproducto));
//Art.SetImageURI(myUri);
Art.SetImageURI(myUri);
}
Button buttonMax = row.FindViewById<Button>(Resource.Id.btnMax);
Button buttonMin = row.FindViewById<Button>(Resource.Id.btnMin);
ImageButton buttonDel = row.FindViewById<ImageButton>(Resource.Id.btnDel);
buttonMax.Click = delegate
{
sList[position].cantidad = sList[position].cantidad 1;
txtCantidad.SetText(Convert.ToString(sList[position].cantidad), TextView.BufferType.Normal);
};
buttonMin.Click = delegate
{
sList[position].cantidad = sList[position].cantidad - 1;
txtCantidad.SetText(Convert.ToString(sList[position].cantidad), TextView.BufferType.Normal);
};
buttonDel.Click = delegate
{
Android.App.AlertDialog.Builder dialog = new AlertDialog.Builder(sContext);
AlertDialog alert = dialog.Create();
alert.SetTitle("GumisaAPP");
alert.SetMessage("Eliminar item : (" position.ToString() ") - " sList[position].codigo sList[position].articulo);
alert.SetIcon(Resource.Drawable.Alerta);
alert.SetButton("OK", (c, ev) =>
{
sList.RemoveAt(position);
NotifyDataSetChanged();
});
alert.SetButton2("CANCEL", (c, ev) =>
{
});
alert.Show();
//mAlertMessageBoxOk.onOkClick(5);
};
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
finally { }
return row;
}
fragment:
private ListView WishlistView;
WishAdapter adapter;
List<EN_WishDetalle> List_Wish = new List<EN_WishDetalle>();
public override View OnCreateView(LayoutInflater inflater, Android.Views.ViewGroup container, Android.OS.Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
//HasOptionsMenu = true;
var view = inflater.Inflate(Resource.Layout.Main_Wish, null);
WishlistView = view.FindViewById<ListView>(Resource.Id.List);
EditText txtCantidad = view.FindViewById<EditText>(Resource.Id.Cantidad);
List_Wish = Variables.WishDetalle;
adapter = new WishAdapter(Activity, List_Wish);
//adapter2 = new WishAdapter( ).;
WishlistView.Adapter = adapter;
//InputSearch = view.FindViewById<EditText>(Resource.Id.inputSearch);
//InputSearch.TextChanged = InputSearch_TextChanged;
//List<EN_Clientes> objstud = new List<EN_Clientes>();
WishlistView = view.FindViewById<ListView>(Resource.Id.List);
Button buttonMax = view.FindViewById<Button>(Resource.Id.btnMax);
Button buttonMin = view.FindViewById<Button>(Resource.Id.btnMin);
ImageButton buttonDel = view.FindViewById<ImageButton>(Resource.Id.btnDel);
WishlistView.ItemClick = buttonMax_ItemClick;
//WishlistView.ItemClick = buttonMin_ItemClick;
//WishlistView.ItemClick = buttonDel_ItemClick;
return view;
}
void buttonMax_ItemClick(object sender,AdapterView.ItemClickEventArgs e)
{
}
void buttonMin_ItemClick(object sender, AdapterView.ItemClickEventArgs x)
{
}
void buttonDel_ItemClick(object sender, AdapterView.ItemClickEventArgs z)
{
}
Also indicate that I have a class with the variable List<EN_WishDetalle> in public to be able to store the information in memory and avoid using the database.
public static List<EN_WishDetalle> WishDetalle = new List<EN_WishDetalle>();
CodePudding user response:
Because of ListView's recycling mechanism, you can use ViewHolder
and button Tag
to achieve this.
Based on your code, I created a simple demo, it works on my side for Button buttonDel
.
You can refer to the following code:
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView; // re-use an existing view, if one is available
MyViewHolder holder;
if (view != null)
{
holder = view.Tag as MyViewHolder;
holder.buttonDel.Tag = position;
//holder.buttonMax.Tag = position;
//holder.buttonMin.Tag = position;
}
else
{ // otherwise create a new one
holder = new MyViewHolder();
LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
view = inflater.Inflate(Resource.Layout.CustomView, null);
holder.HeadingTextView = view.FindViewById<TextView>(Resource.Id.Text1);
holder.SubHeadingTextView = view.FindViewById<TextView>(Resource.Id.Text2);
holder.IconImage = view.FindViewById<ImageView>(Resource.Id.Image);
holder.buttonMax = view.FindViewById<Button>(Resource.Id.btnMax);
holder.buttonMin = view.FindViewById<Button>(Resource.Id.btnMin);
holder.buttonDel = view.FindViewById<ImageButton>(Resource.Id.btnDel);
holder.buttonMax.Click = delegate
{
};
holder.buttonMin.Click = delegate
{
};
holder.buttonDel.Click = delegate
{ // we get the tag here for buttonDel
int position = (int)holder.buttonDel.Tag;
Android.App.AlertDialog.Builder dialog = new AlertDialog.Builder(context);
AlertDialog alert = dialog.Create();
alert.SetTitle("GumisaAPP");
alert.SetMessage("Eliminar item : (" position.ToString() ") - " items[position].Heading items[position].SubHeading);
alert.SetIcon(Resource.Drawable.love);
alert.SetButton("OK", (c, ev) =>
{
items.RemoveAt(position);
NotifyDataSetChanged();
});
alert.SetButton2("CANCEL", (c, ev) =>
{
});
alert.Show();
};
holder.buttonDel.Tag = position;
view.Tag = holder;
}
holder.HeadingTextView.Text = item.Heading;
holder.SubHeadingTextView.Text = item.SubHeading;
holder.IconImage.SetImageResource(item.ImageResourceId);
return view;
}
public class MyViewHolder : Java.Lang.Object
{
public TextView HeadingTextView { get; set; }
public TextView SubHeadingTextView { get; set; }
public ImageView IconImage { get; set; }
public Button buttonMax { get; set; }
public Button buttonMin { get; set; }
public ImageButton buttonDel { get; set; }
}