我在 Xamarin 中有相同的基本可扩展列表,其中包含包含 EditText 的项目。所以基本上列表中的每个项目都有“加 1”或“减 1”以及显示值的 EditText。它基本上是一个购物车,其中有一组物品,并且在一组内您可以购买多个物品。
问题是,当我单击“添加 1”(+1) 按钮时,我会得到完全不同的视图,并且更新其他一些 EditText,而不是同一子视图中的 EditText。
public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
{
Holder<HolderObject> holder;
var child = (JavaObjectWrapper<MobilePOSSubItem>)GetChild(groupPosition, childPosition);
if (convertView == null)
{
convertView = context.LayoutInflater.Inflate(Resource.Layout.mobilePOSTicketsSubItem, null);
holder = new Holder<HolderObject>(
new HolderObject {
GroupPosition = groupPosition,
ChildPosition = childPosition,
Amount = convertView.FindViewById<EditText>(Resource.Id.etAmount),
Tariff = convertView.FindViewById<TextView>(Resource.Id.tariff),
Name = convertView.FindViewById<TextView>(Resource.Id.name),
Rule = convertView.FindViewById<TextView>(Resource.Id.rule),
IconAllotment = convertView.FindViewById<ImageView>(Resource.Id.iconAllotment),
AddButton = convertView.FindViewById<ImageButton>(Resource.Id.add),
RemoveButton = convertView.FindViewById<ImageButton>(Resource.Id.remove)
});
convertView.Tag = holder;
convertView.SetTag(Resource.Id.etAmount, holder.Value.Amount);
convertView.SetTag(Resource.Id.tariff, holder.Value.Tariff);
convertView.SetTag(Resource.Id.name, holder.Value.Name);
convertView.SetTag(Resource.Id.rule, holder.Value.Rule);
convertView.SetTag(Resource.Id.iconAllotment, holder.Value.IconAllotment);
convertView.SetTag(Resource.Id.add, holder.Value.AddButton);
convertView.SetTag(Resource.Id.remove, holder.Value.RemoveButton);
} else
{
holder = (Holder<HolderObject>)convertView.Tag;
holder.Value.Amount.AfterTextChanged -= EtAmount_TextChanged;
}
holder.Value.Amount.SetText(child.Object.Value.ToString(), TextView.BufferType.Editable);
holder.Value.Amount.SetSelectAllOnFocus(true);
holder.Value.Amount.AfterTextChanged += EtAmount_TextChanged;
...
private void EtAmount_TextChanged(object sender, AfterTextChangedEventArgs e)
{
if (sender.GetType().BaseType == typeof(EditText))
{
var etAmount = (EditText)sender;
var parent = (View) etAmount.Parent.Parent;
Holder<HolderObject> holder = (Holder<HolderObject>)parent.Tag;
int value = 0;
string newValue = e.Editable.ToString();
try
{
if (!string.IsNullOrEmpty(newValue))
{
value = Convert.ToUInt16(newValue);
}
else
{
holder.Value.Amount.Text = "0";
}
}
catch
{
holder.Value.Amount.Text = "0";
}
items[holder.Value.GroupPosition].SubItems[holder.Value.ChildPosition].Value = value;
NotifyDataSetChanged();
//UpdateSelectedItem(child, value);
}
}
public void OnClick(View v)
{
HideSoftKeyboard(listView);
View parent = (View) v.Parent.Parent.Parent;
HolderObject holder = ((Holder<HolderObject>)parent.Tag).Value;
var child = (JavaObjectWrapper<MobilePOSSubItem>) GetChild(holder.GroupPosition, holder.ChildPosition);
if (holder.Amount != null)
{
int value;
if (int.TryParse(holder.Amount.Text, out value))
{
if (v.Id.Equals(Resource.Id.add))
{
if (value < 299 && (child.Object.ValueMax == null || value < child.Object.ValueMax))
{
value++;
holder.Amount.Text = value.ToString();
}
}
else if (v.Id.Equals(Resource.Id.remove))
{
if (value > 0 && (child.Object.ValueMin == null || value > child.Object.ValueMin))
{
value--;
holder.Amount.Text = value.ToString();
}
}
}
else
{
holder.Amount.Text = "0";
}
}
else
{
CultureInfo original = CultureInfo.CurrentCulture;
NumberFormatInfo noCurrencySymbol = (NumberFormatInfo)original.NumberFormat.Clone();
noCurrencySymbol.CurrencySymbol = string.Empty;
var cbArticle = (CheckBox)v;
child.Object.ArticleList.FirstOrDefault(x => x.ArticleId == cbArticle.Id).Value = (cbArticle.Checked) ? 1 : 0;
holder.Tariff.Text = string.Format("{0} {1}", child.Object.Currency, child.Object.GetTotalAmount().ToString("C", noCurrencySymbol));
}
}
所以基本上我认为可行的是:
如果我滚动,EditText 值将变为 0,单击按钮将获得完全不同的视图。因此,如果我单击第二组中的第二项(即基于索引的 groupPosition: 1 和 childPosition: 1),我尝试获取 Holder 对象,而 Holder 对象具有 groupPosition:0 和 childPosition:5 这是完全错误的值。
我还设置了稳定的 id,我可以确认所有孩子都有不同的 id:
public override long GetChildId(int groupPosition, int childPosition)
{
return (long) items[groupPosition].SubItems[childPosition].Idx;
}
public override bool HasStableIds
{
get
{
return true;
}
}
问题是这条线
convertView.Tag = holder;
。
将支架附加到视图应该是您在函数中执行的最后一件事,因此我将该行移至函数末尾,并且一切正常,就在 return convertView
之前。错误是我首先将持有者附加到视图,然后更改它并将侦听器添加到持有者视图。这应该是最后一件事,首先将所有内容应用到持有者视图(如文本、侦听器、颜色等),最后将其附加到视图。