ExpandableListView 子视图定位在组展开或滚动

ExpandableListView child views positioning on group expand or scroll

我正在使用扩展 BaseExpandableAdapter 的自定义适配器实现 ExpandableListView

使用 MVP 模型,我成功地以正确的方式膨胀了所有组和视图。我的一块 GetChildView()

public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
{
    BetViewHolder holder = new BetViewHolder(_BetPresenter);
    var view = convertView;

    if (view != null)
        holder = view.Tag as BetViewHolder;
    else
    {
        LayoutInflater layoutInflater = (LayoutInflater)_Context
                        .GetSystemService(Context.LayoutInflaterService);
        holder = new BetViewHolder(_BetPresenter);
        view = layoutInflater.Inflate(Resource.Layout.live_bet_view_item, null);
        holder.InitEventViews(view);

        view.Tag = holder;
    }

    _BetPresenter.OnBindBetEventView(holder, groupPosition, childPosition);

    return view;
}


OnBindBetEventView 的演示者内部,我在相应的视图上设置了数据。

问题

每个子项都有 3 个 select 可用的自定义组件(按钮)。而且总的来说每个子视图都比较复杂。当我 select 子视图的按钮之一时,它成功地更改了颜色,但其他组的其他子视图也更改了 selected。当我滚动或 collapse/expand 一组时,奇怪的部分出现了。

selected 视图正在发生变化,而其他一些视图正在 selected 中。 'Playing' 将所有没有特定模式的 selected 按钮弄乱。

单击第一个按钮还会检查另一个组中的另一个按钮。我还没有 select 编辑它。滚动和展开组会更改 selected 按钮的顺序

注意

经过大量调试后,我意识到每 2 个按钮的唯一视图 ID 都是重复的。这意味着视图的实例完全相同。也许是由于回收或其他原因。关键是我需要保留我的 selected 视图的状态,而不让改编改变我的视图的位置。

由于 reuse-ability 的视图,ExpandableList 的回收机制导致了这种奇怪的行为。带有点击项的 ChildView 一旦离开屏幕就会被回收,并在不同的位置再次膨胀它

我意识到,由于视图具有由 Android 创建的完全相同的唯一哈希值这一事实。有重复

我通过每次适配器尝试膨胀视图时检查我的模型状态来解决它,在它试图膨胀它的位置。

这是从 GetChildView()

的适配器调用的 ViewHolder 方法
public void SetEventToView(Event eventItem)
{
    txtCompetitor1.Text = eventItem.Competitor1;
    txtCompetitor2.Text = eventItem.Competitor2;
    txtTime.Text = eventItem.Time;
    txtScore.Text = eventItem.Score;

    for (int i = 0; i < _OddButtonList.Count; i++)
    {
        _OddButtonList[i].OddID = eventItem.BetItems[i].ID;
        _OddButtonList[i].SetPriceText(eventItem.BetItems[i].BetOdd);
        _OddButtonList[i].SetOnClickListener(this);
        SetButtonState(eventItem, _OddButtonList[i], i);
    }
}