如何在ExpandableListView中更新单个子行?

时间:2016-05-18 13:28:56

标签: android listview expandablelistview baseadapter

我有ExpandableListView,每组中有很多小组和小孩。我需要在活动开始时显示ExpandableListView,但是我有多个后台线程中每行加载的信息,并且需要在线程完成时简单地用它的相应信息更新单个子行。我将Dictionary<int, List<Object>>传递给基本适配器,其中int是组位置的编号。有谁知道我如何能够完美地更新单个子行并且可以解释我的问题?让我知道,非常感谢。

到目前为止,我有:

            var dictionary = _adapter.groupDictionary;
            var rowToUpdate = dictionary.Where(k => k.Value.Any(m => m.Id == _id))
                .ToDictionary(n => n.Key, n => n.Value.Where(o => o.Id == _id).ToList());

            int groupPosition = rowToUpdate.Keys.FirstOrDefault();
            int childPosition = dictionary.Values.FirstOrDefault().IndexOf(rowToUpdate.Values.FirstOrDefault().FirstOrDefault());

            ExpandableListView listView = mView.FindViewById<ExpandableListView>(Resource.Id.listView);
            var flatPosition = listView.GetFlatListPosition(groupPosition);
            int first = listView.FirstVisiblePosition;
            var v = listView.GetChildAt(flatPosition - first);

            if (v == null)
                return;

            TextView someText = (TextView)v.FindViewById(R.id.sometextview);
            someText.SetText("Hi! I updated you manually!");

1 个答案:

答案 0 :(得分:0)

您应该更新适配器中的数据并调用notifyDataSetChanged,而不是更新TextView。这可以通过调用获取子视图的索引来完成(我把它放在Java中,尽可能地匹配C#中的内容):

   _adapter.dictionary.set(group, child);

其中group是组信息,child是子数据。

听起来很浪漫,所以我将进一步解释:在默认的ExpandableListAdapter中,组数据存储在

   List<String> _listDataHeader 

并且子数据存储在

    HashMap <String, List<String>> _listDataChild

其中每个标题字符串映射到子字符串列表。

如果您实现了一个自定义适配器,您可能会为头数据和子数据创建一些类,以便您的_listDataHeader等效于

    List <CustomHeaderData> 

并且您的_listDataChild是

    HashMap <CustomHeaderData, List<CustomChildData>>

或类似的东西。

在getChildView方法中,您的适配器应使用_listDataChild和_listDataHeader来获取CustomChildData(或默认情况下的String),并从数据中设置正确的子视图字段(默认情况下,将TextView文本设置为String)。因此,要更新子视图的外观,请更新_listDataChild中的正确条目并调用notifyDataSetChanged();根据需要重新绘制适当的孩子(例如下面的例子)。

    // Indices from your code
    int groupPosition = rowToUpdate.Keys.FirstOrDefault(); 
    int childPosition = dictionary.Values.FirstOrDefault().IndexOf(rowToUpdate.Values.FirstOrDefault().FirstOrDefault());

    // Get the child from the adapter lists
    CustomGroupData groupData = _listDataHeader.get(groupPosition); // Key for _listDataChild
    List<CustomChildData> childDataList = _listDataChild.get(groupData) ; // List of children
    CustomChildData childData = childDataList.get(childPosition)

    // Make edits to the child as needed
    childData.setSomeDataField("Hi! I updated you manually!");

    // Replace the old child list with an updated list (with updated child)
    childDataList.set(childPosition, childData);
    _listDataChild.put(groupData, childDataList);

    // Tell the adapter to redraw
    notifyDataSetChanged(); // If this function is outside the adapter, 
    // this will have to be called with the instance of your adapter 
    // i.e. mAdapter.notifyDataSetChanged();