我有一个ExpandableListView
位于LinearLayout
容器内,并使用CustomAdapter
进行设置。
对于它的孩子,我使用onGroupClick()
方法向特定服务发送请求并将结果作为String,然后填充点击组项的子列表。
问题,因为我无法获得更新的高度(在服务响应设置为子视图的文本视图的文本视图之后),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 :(得分:4)
使用下面给定的自定义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上充当嵌套滚动父级和子级。默认情况下启用嵌套滚动。
请告诉我这是否对您有所帮助。快乐的编码!!!
答案 1 :(得分:0)
我建议您使用 ExpandableListView 的 HeaderView 属性。 AS ExpandableListView 是 ListView 的派生类,因此我认为HeaderView属性必须存在。
在ScrollView中使用ListView的问题 -
最好将LinearLayout内容移动到另一个视图中,然后根据需要将该视图放大并放入ListView的 Header 或 Footer 。
// 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);