Xamarin Android C#:如何批量上传ListView数据至Firebase实时数据库
解决方案
核心思路
要实现ListView所有数据一次性上传到Firebase同一键下,核心是先把ListView中的所有数据整理成一个集合,再将整个集合上传到Firebase生成的统一父节点下,而非为每个条目单独生成节点。
具体实现(适配你的现有代码)
假设你用来填充两个ListView的数据源是infoName(名称集合)和infoQty(数量集合),且两个集合的元素一一对应,可给“ADD INCLUSIONS”按钮添加如下点击事件:
private void AddInclusionsButton_Click(object sender, EventArgs e) { // 校验两个集合数据数量是否一致,避免数据不匹配 if (infoName.Count != infoQty.Count || infoName.Count == 0) { Toast.MakeText(this.Activity, "数据异常,请检查输入!", ToastLength.Long).Show(); return; } // 1. 整理所有数据为一个集合 List<Java.Util.HashMap> allPackageInfos = new List<Java.Util.HashMap>(); for (int i = 0; i < infoName.Count; i++) { Java.Util.HashMap item = new Java.Util.HashMap(); item.Put("infoName", infoName[i]); item.Put("infoQty", infoQty[i]); allPackageInfos.Add(item); } // 2. 在Firebase生成统一的父节点(用Push保证节点唯一,避免冲突) DatabaseReference parentRef = AppDataHelper.GetDatabase().GetReference("packageinclusions").Push(); // 3. 一次性上传整个集合到父节点下 parentRef.SetValue(allPackageInfos, (error, reference) => { if (error != null) { Toast.MakeText(this.Activity, "上传失败:" + error.Message, ToastLength.Long).Show(); } else { Toast.MakeText(this.Activity, "所有数据上传成功!", ToastLength.Long).Show(); // 上传成功后清空ListView和数据源 infoName.Clear(); infoQty.Clear(); infonameadapter.NotifyDataSetChanged(); infoqtyadapter.NotifyDataSetChanged(); } }); }
优化建议(更规范的做法)
当前用两个ListView分别存名称和数量容易出现数据不同步的问题,建议改用单个ListView+自定义实体类+自定义Adapter的方式管理数据:
- 定义实体类:
public class PackageInfo { public string InfoName { get; set; } public string InfoQty { get; set; } // Firebase序列化需要无参构造函数 public PackageInfo() { } public PackageInfo(string name, string qty) { InfoName = name; InfoQty = qty; } }
- 用单个
List<PackageInfo>作为数据源,自定义Adapter填充ListView(简化版):
public class PackageInfoAdapter : BaseAdapter<PackageInfo> { private readonly Activity _context; private readonly List<PackageInfo> _items; public PackageInfoAdapter(Activity context, List<PackageInfo> items) { _context = context; _items = items; } public override PackageInfo this[int position] => _items[position]; public override int Count => _items.Count; public override long GetItemId(int position) => position; public override View GetView(int position, View convertView, ViewGroup parent) { View view = convertView ?? _context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem2, parent, false); var item = _items[position]; view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = item.InfoName; view.FindViewById<TextView>(Android.Resource.Id.Text2).Text = item.InfoQty; return view; } }
- 上传代码更简洁:
private void AddInclusionsButton_Click(object sender, EventArgs e) { List<PackageInfo> allItems = yourDataSourceList; // 你的PackageInfo集合 if (allItems.Count == 0) { Toast.MakeText(this.Activity, "暂无数据可上传!", ToastLength.Long).Show(); return; } DatabaseReference parentRef = AppDataHelper.GetDatabase().GetReference("packageinclusions").Push(); parentRef.SetValue(allItems, (error, reference) => { if (error != null) { Toast.MakeText(this.Activity, "上传失败:" + error.Message, ToastLength.Long).Show(); } else { Toast.MakeText(this.Activity, "上传成功!", ToastLength.Long).Show(); allItems.Clear(); yourAdapter.NotifyDataSetChanged(); } }); }
说明
- 上传后Firebase的结构示例:
这样你可以通过父键一次性获取所有相关条目,解决之前检索困难的问题。packageinclusions - 随机生成的父键 - 0: { infoName: "xxx", infoQty: "xxx" } - 1: { infoName: "yyy", infoQty: "yyy" } ... Push()方法会生成唯一的随机节点键,避免重复覆盖数据,适合作为一组数据的父节点。
内容的提问来源于stack exchange,提问作者Zeno
相关产品推荐
相关产品推荐

