2

У меня есть ExpandableListView, который находится внутри контейнера LinearLayout и устанавливается с помощью CustomAdapter.
Для своих детей я использую метод onGroupClick() для отправки запроса на конкретную услугу и получения результата в виде строки, а затем заполнения списка дочерних элементов группы.ExpandableListView динамический рост ребенка

Проблема, так как я не могу получить обновленную высоту (после того, как ответ службы установлен в текстовое представление текстового вида детского вида), высота контейнера linearlayout не увеличивается так, как должна. И это также создает проблему прокрутки.

Хотя элемент списка ребенок XML является WRAP_CONTENT, как показано ниже:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/root" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:minHeight="@dimen/rowHeight" 
android:background="@color/colorLightYellow"> 

<TextView 
    android:id="@+id/tvTitle" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_centerVertical="true" 
    android:layout_marginLeft="@dimen/marginGeneral" 
    android:layout_toLeftOf="@+id/tvCount" 
    android:gravity="center_vertical" 
    android:paddingBottom="@dimen/marginGeneral" 
    android:paddingTop="@dimen/marginGeneral" 
    android:text="tvTitle" 
    android:textColor="@color/colorGray" 
    android:textSize="@dimen/fontSizeNormal" /> 
... 
</RelativeLayout> 

Так что часть кода мало длительного пребывания со мной:

@Override 
public boolean onGroupClick(ExpandableListView parent, View v, final int groupPosition, long id) { 
    Map<Item, List<ItemDetail>> childList = detailExpandableAdapter.getChildList(); 
    final Item item = detailExpandableAdapter.getGroup(groupPosition); 
    if (childList.get(item).size() == 0) { 
     startProgressDialog(); 

     GlobalApplication.getService().getItemDetails(Session.getCurrent().getSessionId(), getItem.item.itemNo, item.name, new ServiceCallback<GetItemDetails>() { 
      @Override 
      public void onSuccess(GetItemDetails response) { 
       stopProgressDialog(); 

       List<ItemDetail> itemDetailList = null; 

       if (GetItemDetails.isSuccess(response)) { 
        itemDetailList = response.getItemDetailList(); 
       } else { 
        itemDetail itemDetail = new ItemDetail(); 
        itemDetail.resultDesc = response.getResult().getResultDesc(); 

        if (StringUtils.isNullOrWhitespace(itemDetail.resultDesc)) { 
         itemDetail.resultDesc = Result.getGeneralFailResult().getResultDesc(); 
        } 

        itemDetailList = new ArrayList<ItemDetail>(); 
        itemDetailList.add(itemDetail); 
       } 

       if (itemDetailList != null) { 
        Map<Item, List<ItemDetail>> childList = detailExpandableAdapter.getChildList(); 

        if (childList.containsKey(item)) { 
         childList.remove(item); 
        } 
        childList.put(item, itemDetailList); 

        detailExpandableAdapter.setChildList(childList); 
        detailExpandableAdapter.notifyDataSetChanged(); 
        detailExpandableAdapter.notifyDataSetInvalidated(); 

        listViewLastItems.expandGroup(groupPosition); 
       } 
      } 

      @Override 
      public void onFail() { 
       stopProgressDialog(); 
      } 
     }); 

     return false; 
    } 

    return false; 
} 

@Override 
public void onGroupExpand(int groupPosition) { 
    setExpandableListViewHeightStable(listViewLastItems, llListViewItemDetailContainer); 
    if (lastExpanded != -1 && groupPosition != lastExpanded) 
     listViewItems.collapseGroup(lastExpanded); 
    lastExpanded = groupPosition; 
} 

public void setExpandableListViewHeight(ExpandableListView expandableListView, LinearLayout linearLayoutParent){ 
    try { 
     ExpandableListAdapter expandableListAdapter = expandableListView.getExpandableListAdapter(); 

     int totalHeight = 0; 
     int desiredWidth = View.MeasureSpec.makeMeasureSpec(expandableListView.getWidth(), View.MeasureSpec.UNSPECIFIED); 

     for (int i = 0; i < expandableListAdapter.getGroupCount(); i++) { 
      View groupItem = expandableListAdapter.getGroupView(i, false, null, expandableListView); 
      groupItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED); 

      //Logger.debug("recalculateExpandableListViewHeight listItem:"+groupItem.getMeasuredHeight()); 
      totalHeight += groupItem.getMeasuredHeight(); 

      if (expandableListView.isGroupExpanded(i)){ 
       for (int j = 0; j < expandableListAdapter.getChildrenCount(i); j++) { 
        View listItemChild = expandableListAdapter.getChildView(i, j, false, null, expandableListView); 

        listItemChild.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, View.MeasureSpec.UNSPECIFIED)); 
        listItemChild.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 

        Logger.debug("recalculateExpandableListViewHeight listItemChild:" + listItemChild.getMeasuredHeight()); 
        totalHeight += listItemChild.getMeasuredHeight(); 
       } 
      } 
     } 

     linearLayoutParent.getLayoutParams().height = totalHeight + (expandableListAdapter.getGroupCount() * expandableListView.getDividerHeight()); 
     linearLayoutParent.requestLayout(); 
    } catch (Exception e) { 
     Logger.printStackTrace(e); 
    } 
} 

Update: это линейная компоновка я использую в качестве контейнера

<LinearLayout 
       android:id="@+id/llListViewItemContainer" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_below="@+id/tvItemDueDate" 
       android:layout_marginTop="@dimen/marginGeneral" 
       android:orientation="vertical"/> 

Обновление 2: Я динамически добавляю ExpandableListView в LinearLayout.

listViewItems = new ExpandableListView(getContext()); 
listViewItems.setScrollContainer(false); 
listViewItems.setDivider(new ColorDrawable(getResources().getColor(R.color.colorLightGray))); 
listViewItems.setDividerHeight(UIHelper.convertDptoPixels(1)); 
listViewItems.setGroupIndicator(null); 
listViewItems.setOnGroupClickListener(this); 
listViewItems.setOnGroupExpandListener(this); 
listViewItems.setOnGroupCollapseListener(this); 
//generate empty child list 
Map<Item, List<ItemDetail>> childMap = new HashMap<>(); 
for (Item item : getItems.getItemList()) { 
    childMap.put(item, new ArrayList<ItemDetail>()); 
       } 
detailExpandableAdapter = new detailExpandableAdapter(getActivity(), getItems.getItemList(), childMap); 
listViewItems.setAdapter(detailExpandableAdapterF); 
listViewItems.removeAllViews(); 
listViewItems.addView(listViewLastItems); 
UIHelper.setExpandableListViewHeightStable(listViewItems, llListViewDetailContainer); 
+0

Я думаю, вы можете использовать RecyclerView вместо LinearLayout (контейнер). – Sabari

+0

, так что родитель линейного макета обернут внутри scrollView? – HourGlass

+0

Вы пробовали это решение? http://thedeveloperworldisyours.com/android/expandable-listview-inside-scrollview/#sthash.sW6JMsU5.dpbs –

ответ

3

Использование ниже данного пользовательского класса ExpandableListView и переопределить метод onMeasure.

public class MyExpandableListView extends ExpandableListView { 

    public MyExpandableListView(Context context) { 
     super(context); 
    } 

    public MyExpandableListView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public MyExpandableListView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
       Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom); 
     ViewGroup.LayoutParams params = getLayoutParams(); 
     params.height = getMeasuredHeight(); 
    } 
} 

И использовать его как,

<com.app.custom.NonScrollExpandableListView 

    android:layout_width="match_parent" 
    android:layout_height="wrap_content" /> 

Заменить com.app.custom с вашим именем пакета, в котором вы положили этот пользовательский класс.

Если возможно, используйте NestedScrollView, а не ScrollView, так как он поддерживает как родительскую, так и дочернюю вставку с прокруткой на обеих новых и старых версиях Android. Вложенная прокрутка включена по умолчанию.

Дайте мне знать, если это поможет вам или нет. Счастливое кодирование !!!

+0

Это не help, линейная компоновка расширяется как высота динамического элемента, но пропускает другие предметы. –

+0

Не получилось. Пожалуйста, уточните, что происходит. –

+0

Попробуйте использовать NestedScrollView или собственный класс LinearLayout (такой же, как MyExpandableListView, но расширяет LinearLayout). Вы добавляете ExpandableListView в контейнер Linearlayout динамически? Если да, то, пожалуйста, вставьте его код. –

0

Я предлагаю вам использовать HeaderView Недвижимость ExpandableListView. AS ExpandableListView - это производный класс ListView, поэтому свойство HeaderView должно быть там, как я полагаю.

Проблемы с использованием ListView внутри ScrollView -

  1. Производительность - Если вы собираетесь играть с мерой свойство ListView, то он, несомненно, влияет на рециркуляции клеток.
  2. Пользовательский опыт: странное поведение возникает, когда родителем ListView является другое прокручиваемое представление.

лучше переместить LinearLayout вещи в другой точке зрения, то раздувать эту точку зрения и либо поместить его в Заголовок или Footer из ListView в соответствии с вашими потребностями.

// Inflated View which is going to be use as Header of view 
    ViewGroup headerView = (ViewGroup)getLayoutInflater().inflate(R.layout.list_header,expListView,false); 
    // Add that view to Header 
    your_expandale_listView.addHeaderView(headerView); 
Смежные вопросы