如何收集GridView选中项并传递至下一个Fragment进行支付
问题描述
我正在开发支付功能,我的GridView中每个条目都带有CheckBox,需要将选中的网格项包含所有字段传递到下一个Fragment并进行相关计算。我尝试了以下代码,但目前只能计算选中项的金额,不知道如何获取包含所有字段的选中条目:
btnPtoPay.Click += delegate { for (int x = 0; x < tableGrid.ChildCount; x++) { var checkbox = (CheckBox)tableGrid.GetChildAt(x).FindViewById(Resource.Id.txtCellFive); var tvSelectedAmount = (TextView)tableGrid.GetChildAt(x).FindViewById(Resource.Id.txtCelltwo); var tvAmountPaid = (TextView)tableGrid.GetChildAt(x).FindViewById(Resource.Id.txtCelltwo); decimal totalM = 0; if (checkbox.Checked) { totalM = totalM+ Convert.ToDecimal(tvSelectedAmount.Text); //Here how to get selected item, with all fields } }; var fragmentTx = Activity.SupportFragmentManager.BeginTransaction(); var feePay = new FeePaymentFragment(); fragmentTx.Replace(Resource.Id.crealtabcontent, feePay, "feedPayFragmentTag").AddToBackStack("feePayfrg"); fragmentTx.Commit(); };
解决方案
嗨,我来帮你搞定这个问题!直接从GridView的子View里提取所有字段其实很容易踩坑(比如GridView复用View导致数据错位),最靠谱的方式是基于数据模型来处理,而非直接操作UI控件。按下面的步骤来做就能轻松获取带全字段的选中条目:
1. 创建数据模型类
首先为你的GridView条目创建一个模型类,把所有需要的字段都包含进去,比如:
public class FeeItem { public string Id { get; set; } // 可选,比如条目唯一标识 public string Amount { get; set; } // 待支付金额 public string PaidAmount { get; set; } // 已支付金额 public string Description { get; set; } // 比如费用描述 public bool IsChecked { get; set; } // 记录当前条目是否被选中 }
2. 改造GridView的自定义Adapter
把Adapter的数据源换成List<FeeItem>,绑定View的时候将控件和模型字段关联,同时给CheckBox添加点击事件,实时更新模型的选中状态:
public class FeeAdapter : BaseAdapter<FeeItem> { private List<FeeItem> _feeItems; private Context _context; public FeeAdapter(Context context, List<FeeItem> feeItems) { _context = context; _feeItems = feeItems; } // 暴露数据源,方便后续筛选选中项 public List<FeeItem> Items => _feeItems; public override FeeItem this[int position] => _feeItems[position]; public override int Count => _feeItems.Count; public override long GetItemId(int position) => position; public override View GetView(int position, View convertView, ViewGroup parent) { // 复用View,优化性能 View view = convertView ?? LayoutInflater.From(_context).Inflate(Resource.Layout.your_grid_item_layout, parent, false); var currentItem = _feeItems[position]; // 绑定各个字段到TextView var tvAmount = view.FindViewById<TextView>(Resource.Id.txtCelltwo); var tvPaidAmount = view.FindViewById<TextView>(Resource.Id.txtCellthree); var tvDesc = view.FindViewById<TextView>(Resource.Id.txtCellOne); tvAmount.Text = currentItem.Amount; tvPaidAmount.Text = currentItem.PaidAmount; tvDesc.Text = currentItem.Description; // 绑定CheckBox并关联模型的选中状态 var checkBox = view.FindViewById<CheckBox>(Resource.Id.txtCellFive); checkBox.Checked = currentItem.IsChecked; checkBox.Click += (sender, e) => { // 点击CheckBox时实时更新模型的选中状态 currentItem.IsChecked = checkBox.Checked; }; return view; } }
3. 收集选中条目并传递到目标Fragment
点击支付按钮时,直接从Adapter的数据源中筛选出选中的FeeItem,然后通过Bundle传递给下一个Fragment:
btnPtoPay.Click += delegate { // 获取Adapter实例 var feeAdapter = (FeeAdapter)tableGrid.Adapter; // 筛选出所有选中的条目 var selectedItems = feeAdapter.Items.Where(item => item.IsChecked).ToList(); // 计算总金额(也可以在目标Fragment里计算) decimal totalM = selectedItems.Sum(item => Convert.ToDecimal(item.Amount)); // 准备传递数据到FeePaymentFragment var fragmentTx = Activity.SupportFragmentManager.BeginTransaction(); var feePay = new FeePaymentFragment(); // 用Bundle传递数据,这里推荐用Json序列化(避免Serializable的限制) var json = Newtonsoft.Json.JsonConvert.SerializeObject(selectedItems); var bundle = new Bundle(); bundle.PutString("SelectedFeeItems", json); feePay.Arguments = bundle; fragmentTx.Replace(Resource.Id.crealtabcontent, feePay, "feedPayFragmentTag").AddToBackStack("feePayfrg"); fragmentTx.Commit(); };
4. 在目标Fragment中接收并使用数据
在FeePaymentFragment的OnCreateView方法中,取出传递过来的数据,就可以拿到带全字段的选中条目了:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { var view = inflater.Inflate(Resource.Layout.fee_payment_layout, container, false); if (Arguments != null && Arguments.ContainsKey("SelectedFeeItems")) { var json = Arguments.GetString("SelectedFeeItems"); var selectedItems = Newtonsoft.Json.JsonConvert.DeserializeObject<List<FeeItem>>(json); // 现在你可以用这些选中条目做任何计算或展示了 foreach(var item in selectedItems) { // 访问item的所有字段:item.Id、item.Amount、item.Description等 } } return view; }
为什么不推荐直接操作GridView的子View?
GridView会复用View来优化性能,当你滚动GridView后,tableGrid.GetChildAt(x)获取到的View对应的位置可能已经不是原来的数据项了,直接从View中提取数据很容易出现数据错位的问题,而基于数据模型的方式则完全避免了这个问题,代码也更易维护。
内容的提问来源于stack exchange,提问作者Arvind Chourasiya
相关产品推荐
相关产品推荐

