У меня проблема. У меня есть ExpandableListView
и пользовательский адаптер, который распространяется от BaseExpandableListAdapter
. И у меня есть ArrayList
, который содержит элементы моих групп и групп.После удаления элемента из списка позиция расширенного элемента не обновляется на ExpandableListView - Android?
Проблема заключается в том:
1) Развернуть 3-й группы.
2) Удалить первый элемент из ArrayList и notifyDataSetInvalidated
, notifyDataSetChanged
3) getGroupView
запрашивается право, и я могу установить его, что мне нужно.
4) Но getChildView
запрашивается для старого положения (3). Когда первый элемент удаляется, индексы изменяются. Но ListView
пытается получить детское видение старой позиции.
Это мое понимание. Где может быть проблема?
Это мой адаптер:
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;
}
}}
Пожалуйста, поделитесь часть кода для правильного понимания в проблемы и быстро получить решение :) –
@SanifSS I добавила мой адаптер, благодаря вашему совету. – atasoyh