2016-11-04 135 views
2

我有一個ExpandableListView這是一個LinearLayout作爲容器內和使用CustomAdapter設置。
對於它的孩子,我使用onGroupClick()方法向特定服務發送請求,並以String結果結果,然後填充點擊的組項目的子列表。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); 
    } 
} 

更新:這是線性佈局我作爲容器使用

<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

它沒有線性佈局隨着動態物品的高度變寬,但跳過其他物品 –

+0

Did not get you。請詳細說明會發生什麼。 –

+0

嘗試使用NestedScrollView或自定義LinearLayout類(與MyExpandableListView相同,但擴展了LinearLayout)。你是否在Linearlayout容器中動態添加ExpandableListView?如果是,那麼請粘貼它的代碼。 –

0

我會建議你使用HeaderView ExpandableListView財產。 AS ExpandableListView是派生類ListView所以HeaderView屬性必須在那裏,因爲我相信。

問題在裏面使用滾動型的ListView -

  1. 性能 - 如果你要與ListView控件的措施財產玩那麼自然會影響細胞再生的。
  2. 用戶體驗 - 當ListView的父項是另一個可滾動視圖時出現奇怪行爲。

更好地將您的LinearLayout東西另一個視圖內,然後膨脹這一觀點,要麼把它放在頁腳的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);