You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何收集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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:59:45