android - 从列表中删除项目后,展开项目的位置不会在 ExpandableListView 上刷新 - Android?

标签 android listview expandablelistview android-listfragment expandablelistadapter

我有一个问题。我有一个 ExpandableListView 和一个从 BaseExpandableListAdapter 扩展而来的自定义适配器。我有一个 ArrayList,其中包含我的组和组的子项。

问题是:

1) 展开第三组。

2) 删除ArrayList中的第一项和notifyDataSetInvalidated, notifyDataSetChanged

3) getGroupView 请求正确,我可以根据需要进行设置。

4) 但是 getChildView 被请求用于旧位置 (3)。删除第一项时,索引会更改。但是 ListView 试图获取旧位置的 subview 。

这是我的理解。问题出在哪里?

这是我的适配器:

public class DashboardAdapter extends BaseExpandableListAdapter implements View.OnClickListener {

private static final String TAG = DashboardAdapter.class.getSimpleName();
private static final int groupTypeCount = GroupType.values().length;
private final Activity activity;
private final ExpandableListView exListView;
private final List<Object> dashboard = new ArrayList<>();
private String lastExpandedProductIban = null;

public DashboardAdapter(final Activity activity, ExpandableListView expandableListView) {
    this.activity = activity;
    exListView = expandableListView;
}

public void setDashboard(final List<Object> dashboard) {
    if (Verify.notNull(dashboard)) {
        this.dashboard.clear();
        this.dashboard.addAll(dashboard);
}


@Override
public int getGroupTypeCount() {
    return groupTypeCount;
}

@Override
public int getGroupType(int groupPosition) {
    final Object group = getGroup(groupPosition);
    if (group instanceof Dashboard.Products.Accordion)
        return GroupType.PRODUCT_ACCORDION.ordinal();

    return -1;
}

@Override
public int getGroupCount() {
    return dashboard.size();
}

@Override
public int getChildrenCount(int groupPosition) {
    if (getGroupType(groupPosition) == GroupType.PRODUCT_ACCORDION.ordinal())
        return ((Dashboard.Products.Accordion) getGroup(groupPosition)).actions.size();
    return 0;
}

@Override
public Object getGroup(int groupPosition) {
    if (groupPosition >= 0 && groupPosition < dashboard.size())
        return dashboard.get(groupPosition);
    return null;
}

@Override
public Object getChild(int groupPosition, int childPosition) {
    if (getGroupType(groupPosition) == GroupType.PRODUCT_ACCORDION.ordinal()) {
        final Dashboard.Products.Accordion group = (Dashboard.Products.Accordion) getGroup(groupPosition);

        if (group != null && childPosition >= 0 && childPosition < group.actions.size())
            return group.actions.get(childPosition);
    }
    return null;
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

@Override
public boolean hasStableIds() {
    return true;
}

@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    // initialise all possible ViewHolders
    ViewHolderAccordion viewHolderAccordion = null;
    // get GroupType of the current View
    final GroupType groupType = GroupType.valueOf(getGroupType(groupPosition));

    // Inflate the layout if convertView is null
    if (convertView == null) {
        LayoutInflater inflater = activity.getLayoutInflater();

        switch (groupType) {
            case PRODUCT_ACCORDION:
                convertView = inflater.inflate(R.layout.item_dashboard_accordion, parent, false);
                viewHolderAccordion = new ViewHolderAccordion(convertView);
                break;
        }
    }
    // reuse convertView if it isn't null
    else {
        switch (groupType) {
            case PRODUCT_ACCORDION:
                viewHolderAccordion = ((ViewHolderAccordion) convertView.getTag()).reset();
                break;
        }
    }



    if (viewHolderAccordion != null) {
        final Dashboard.Products.Accordion accordion = (Dashboard.Products.Accordion) getGroup(groupPosition);

        // set alternating background color
        //if(dashboardGroups.accounts.indexOf(account) % 2 == 0)
        //convertView.setBackgroundColor(activity.getResources().getColor(R.color.dashboard_account_alternate_color));

        // populate view with content
        if (accordion != null) {
            setText(viewHolderAccordion.tvProductAccordionName, accordion.title);
            setText(viewHolderAccordion.tvProductAccordionDetail, accordion.detail);
            setText(viewHolderAccordion.tvProductAccordionBalance, accordion.balance);

            boolean _isExpanded = getPositionFromIban(lastExpandedProductIban) == groupPosition;
            accordion.isExpanded = _isExpanded;
            viewHolderAccordion.groupExpander.setImageResource(_isExpanded ? R.drawable.expander_white_close : R.drawable.expander_open);
            viewHolderAccordion.contentView.setActivated(_isExpanded ? true : false);
            viewHolderAccordion.dashboard_product_accordion_divider.setVisibility(_isExpanded ? View.GONE : View.VISIBLE);
        }
        convertView.setTag(viewHolderAccordion);
    }


    return convertView;
}

private void deleteCell(final View view, final int groupPosition) {
    final Animation.AnimationListener animationListener = new Animation.AnimationListener() {
        @Override
        public void onAnimationEnd(Animation arg0) {
            dashboard.remove(groupPosition);
            notifyDataSetInvalidated();
            notifyDataSetChanged();


        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationStart(Animation animation) {
        }
    };

    collapse(view, animationListener);
}

private void collapse(final View view, final Animation.AnimationListener al) {
    final int initialHeight = view.getMeasuredHeight();

    Animation anim = new Animation() {
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            if (interpolatedTime == 1) {
                view.setVisibility(View.GONE);
            } else {
                view.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
                view.requestLayout();
            }
        }

        @Override
        public boolean willChangeBounds() {
            return true;
        }
    };

    if (al != null) {
        anim.setAnimationListener(al);
    }
    anim.setDuration(200);
    view.startAnimation(anim);
}

@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    if (getGroupType(groupPosition) == GroupType.PRODUCT_ACCORDION.ordinal()) {

        final Dashboard.Products.Accordion.Action action =
                (Dashboard.Products.Accordion.Action) getChild(groupPosition, childPosition);
        if (action != null) {
            ViewHolderAccordionLink viewHolderAccordionLink;
            if (convertView == null) {
                LayoutInflater inflater = activity.getLayoutInflater();
                convertView = inflater.inflate(R.layout.item_dashboard_accordion_link, parent, false);
                viewHolderAccordionLink = new ViewHolderAccordionLink(convertView);
            } else {
                viewHolderAccordionLink = ((ViewHolderAccordionLink) convertView.getTag()).reset();
            }

            // populate view with content
            if (viewHolderAccordionLink != null) {
                if (Verify.notNull(action.icon)) {
                    viewHolderAccordionLink.ivAccordionLink.setVisibility(View.VISIBLE);
                } else {
                    viewHolderAccordionLink.ivAccordionLink.setVisibility(View.GONE);
                }
                if (action.title != null) {
                    setText(viewHolderAccordionLink.tvAccordionLinkLabel, action.title);
                }

                convertView.setTag(viewHolderAccordionLink);
            }
        }

    }
    return convertView;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return getChildrenCount(groupPosition) > 0;
}

@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEmpty() {
    return dashboard.size() == 0;
}

@Override
public void onGroupExpanded(int groupPosition) {
}

@Override
public void onGroupCollapsed(int groupPosition) {

}

private void setText(final TextView textView, final DashboardText text) {
    if (text != null) {
        textView.setVisibility(View.VISIBLE);
        if (Verify.notNull(text.text)) {
            textView.setText(Html.fromHtml(text.text));
        }
        switch (text.color) {
            case BLACK:
                textView.setTextColor(activity.getResources().getColorStateList(R.color.selector_dashboard_black));
                break;
            case ORANGE:
                textView.setTextColor(activity.getResources().getColorStateList(R.color.selector_dashboard_orange));
                break;
            case RED:
                textView.setTextColor(activity.getResources().getColorStateList(R.color.selector_dashboard_red));
                break;
            case GREEN:
                textView.setTextColor(activity.getResources().getColorStateList(R.color.selector_dashboard_green));
                break;
            case GREY:
                textView.setTextColor(activity.getResources().getColorStateList(R.color.selector_dashboard_grey));
                break;
            case WHITE:
                textView.setTextColor(activity.getResources().getColor(R.color.white));
                break;
        }
    } else {
        textView.setVisibility(View.GONE);
    }
}

public String getIbanAtPosition(int groupPosition) {

    if (getGroupType(groupPosition) == GroupType.PRODUCT_ACCORDION.ordinal()) {
        final Dashboard.Products.Accordion group = (Dashboard.Products.Accordion) getGroup(groupPosition);

        if (group != null) {
            return group.detail.text;
        }
    }

    return null;

}

public int getPositionFromIban(String iban) {
    if (dashboard != null) {
        for (int groupPosition = 0; groupPosition < dashboard.size(); groupPosition++) {
            if (getGroupType(groupPosition) == GroupType.PRODUCT_ACCORDION.ordinal()) {
                Dashboard.Products.Accordion group = (Dashboard.Products.Accordion) getGroup(groupPosition);
                if (group.detail.text.equalsIgnoreCase(iban))
                    return groupPosition;
            }
        }
    }
    return -1;
}

public void setLastExpandedProductIban(String lastExpandedProductIban) {
    this.lastExpandedProductIban = lastExpandedProductIban;
}

private enum GroupType {
    PERSONALIZATION, PRODUCT_ACCORDION;

    // Converts from an ordinal value to the Groups
    public static GroupType valueOf(final int index) {
        final GroupType[] values = GroupType.values();
        if (index < 0 || index >= values.length) {
            return PERSONALIZATION;
        }
        return values[index];
    }
}



class ViewHolderAccordion {
    public View contentView;
    public ImageView groupExpander;
    public TextView tvProductAccordionName;
    public TextView tvProductAccordionDetail;
    public TextView tvProductAccordionBalance;
    public View dashboard_product_accordion_divider;

    public ViewHolderAccordion(View contentView) {
        this.contentView = contentView;
        groupExpander = (ImageView) contentView.findViewById(R.id.groupExpander);
        tvProductAccordionName = (TextView) contentView.findViewById(R.id.tvProductAccordionName);
        tvProductAccordionDetail = (TextView) contentView.findViewById(R.id.tvProductAccordionDetail);
        tvProductAccordionBalance = (TextView) contentView.findViewById(R.id.tvProductAccordionBalance);
        dashboard_product_accordion_divider = contentView.findViewById(R.id.dashboard_product_accordion_divider);
    }

    public ViewHolderAccordion reset() {
        //contentView.setBackgroundColor(0xFFffffff);
        tvProductAccordionName.setText("");
        tvProductAccordionDetail.setText("");
        tvProductAccordionDetail.setVisibility(View.VISIBLE);
        tvProductAccordionBalance.setText("");
        return this;
    }
}}

最佳答案

我可以用

解决这个问题
@Override
public long getGroupId(int groupPosition) {
    return dashboard.get(groupPosition).hashCode();
}

代替

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

关于android - 从列表中删除项目后,展开项目的位置不会在 ExpandableListView 上刷新 - Android?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36916903/

相关文章:

java - 导航栏可扩展 ListView android

java - 是否可以保存时间选择器的数据并在下次应用程序启动时显示它们?

java - java.util.Scanner 有那么慢吗?

java - 如何使用AdapterView.INVALID_ROW_ID?

c# - 如何获得目标 ListView 项目?

android - 在 fragment 中添加可扩展列表

android - 如何将套接字/文件描述符传递给Android中的其他应用程序

android - 突出显示 "ListFragment"中的选定项目?

Android ListView丢失项目高度

android - 在Android中将ExpandableListView的指示器放在右侧