【问题标题】:How to Measure child expandable list height and width如何测量子可扩展列表的高度和宽度
【发布时间】:2013-04-02 06:49:46
【问题描述】:

我正在使用可扩展列表视图来制作 3 级层次结构,想知道如何设置内部列表的高度和宽度。 我知道我们为此目的有 onMeasure,但就我而言,它不允许我捕获父列表视图的整个空间。

可能是我给出了错误的值,这是我用于设置子可扩展列表的高度和宽度的代码。

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    {

        widthMeasureSpec = MeasureSpec.makeMeasureSpec(960,MeasureSpec.AT_MOST);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(800,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

目前显示如下

<ParentGroup1                >
<ChildParentGroup>
<Child1>
<Child2>
<child3>
<ParentGroup2                >

它应该如下所示。

<ParentGroup1                >
<ChildParentGroup            >
<Child1                      >
<Child2                      >
<child3                      >
<ParentGroup2                >

请同样建议/建议。

感谢您的宝贵时间。

【问题讨论】:

  • 你能用任何截图解释你的可扩展列表视图吗?
  • 嗨 Venkata,我没有那个 repo 来上传堆栈溢出的图像但是,我可以告诉你我面临的问题请参考更新的问题
  • 所有的父母,所有的子父母和孩子是否有相同的布局设计?
  • 是的,所有都使用相同的布局

标签: android android-layout expandablelistview


【解决方案1】:

不确定您是否还在寻找答案,但我就是这样做的:在构造函数来创建子自定义列表。

public CustomExpandableList(Context context, View the_parentView, int the_heightMeasure)
{ 
    super(context);
    WIDTH = the_parentView!=null?the_parentView.getWidth():LayoutParams.MATCH_PARENT;
    HEIGHT = the_heightMeasure * 500;
}

编辑:或者为了使代码更加一致,您可以将 parentView 的宽度和高度度量传递给构造函数,而不是传递父视图本身。 CustomExpandableList(上下文 the_context, int the_width, int the_heightMeasure)

【讨论】:

  • 感谢您的宝贵反馈。我想,我用其他方式解决了它,我也会应用它并让我们知道。
【解决方案2】:

使用此代码动态计算可扩展列表视图:

    // calculate the height of expandable listView without expanded
      private void setListViewHeight(ExpandableListView expListView) {
    ListAdapter listAdapter = expListView.getAdapter();
    int totalHeight = 0;

    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, expListView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
        System.out.println("i  " + i);
    }

    ViewGroup.LayoutParams params = expListView.getLayoutParams();
    params.height = totalHeight
            + (expListView.getDividerHeight() * (listAdapter.getCount() - 1));
    System.out.println("params.height =  " + params.height);

    expListView.setLayoutParams(params);
    expListView.requestLayout();
}

// calculate the height of expandable listview dynamically
private void setListViewHeight(ExpandableListView expListView, int group) {

    ExpandableListAdapter listAdapter = expListView
            .getExpandableListAdapter();
    int totalHeight = 0;
    int desiredWidth = MeasureSpec.makeMeasureSpec(expListView.getWidth(),
            MeasureSpec.UNSPECIFIED);
    for (int i = 0; i < listAdapter.getGroupCount(); i++) {
        View groupItem = listAdapter.getGroupView(i, false, null,
                expListView);
        groupItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);

        totalHeight += groupItem.getMeasuredHeight();

        if (((expListView.isGroupExpanded(i)) && (i == group))
                || ((!expListView.isGroupExpanded(i)) && (i == group))) {

            for (int j = 0; j < listAdapter.getChildrenCount(i); j++) {

                View listItem = listAdapter.getChildView(i, j, false, null,
                        expListView);

                Log.e("Count", listAdapter.getChildrenCount(i) + "");

                listItem.setLayoutParams(new ViewGroup.LayoutParams(
                        desiredWidth, MeasureSpec.UNSPECIFIED));
                // listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
                listItem.measure(MeasureSpec.makeMeasureSpec(0,
                        MeasureSpec.UNSPECIFIED), MeasureSpec
                        .makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
                totalHeight += listItem.getMeasuredHeight();

                System.out.println("totalHeight" + totalHeight);
                Log.e("TEST", "gshdkfmjfy,");

            }
        }
    }

    ViewGroup.LayoutParams params = expListView.getLayoutParams();
    int height = totalHeight
            + (expListView.getDividerHeight() * (listAdapter
                    .getGroupCount() - 1));

    if (height < 10) {
        height = 100;
    }
    params.height = height;
    expListView.setLayoutParams(params);
    expListView.requestLayout();

}

【讨论】:

  • 我想知道,我传入private void setListViewHeight(ExpandableListView expListView, int group)的int group的值是多少
【解决方案3】:

几天前我通过这样做成功了。它更紧凑一点,没有任何附加参数,而且效果很好。

public static void setExpandableListViewHeightBasedOnChildren(ExpandableListView expandableListView){
    ExpandableNotesListAdapter adapter = (ExpandableNotesListAdapter) expandableListView.getExpandableListAdapter();
    if (adapter == null){
        return;
    }
    int totalHeight = expandableListView.getPaddingTop() + expandableListView.getPaddingBottom();
    for (int i = 0 ; i < adapter.getGroupCount() ; i++){
        View groupItem = adapter.getGroupView(i, false, null, expandableListView);
        groupItem.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED);
        totalHeight += groupItem.getMeasuredHeight();

        if (expandableListView.isGroupExpanded(i) ){
            for( int j = 0 ; j < adapter.getChildrenCount(i) ; j++) {
                View listItem = adapter.getChildView(i, j, false, null, expandableListView);
                listItem.setLayoutParams(new LayoutParams(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED));
                listItem.measure(View.MeasureSpec.makeMeasureSpec(0,
                        View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
                        .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                totalHeight += listItem.getMeasuredHeight();

            }
        }
    }

    ViewGroup.LayoutParams params = expandableListView.getLayoutParams();
    int height = totalHeight + expandableListView.getDividerHeight() * (adapter.getGroupCount() - 1);

    if (height < 10)
        height = 100;
    params.height = height;
    expandableListView.setLayoutParams(params);
    expandableListView.requestLayout();
}

在初始化视图、设置适配器等时不要忘记添加它:

Functions.setExpandableListViewHeightBasedOnChildren(listView);
listView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
    @Override
    public void onGroupExpand(int groupPosition) {
        Functions.setExpandableListViewHeightBasedOnChildren(listView);
    }
});

【讨论】:

    【解决方案4】:

    为 ParentGroup 和 ChildParentGroup 创建一个布局 xml 文件,为 Child 创建另一个布局 xml 文件。现在你的问题被简化为两级层次结构。然后在可扩展列表视图中,我们有父视图和子视图方法来膨胀和使用父和子布局。因此,在这种方法中,您可以为所欲为。

    【讨论】:

    • 对不起 Venkata,但我的方法与您在答案中提到的类似,因为我得到了有线输出。简而言之,我有一个可扩展的列表视图,它使用 A-Adapter 在 getChildView 上填充其数据我正在创建 B-Expandable Listview 并使用 B-Adapter。现在的问题是当我删除 B-Expandable 的 onmessaue 方法时,B - 可扩展列表使用 A- 可扩展列表的整个宽度,但 B 的子视图不可见。
    【解决方案5】:

    只需删除宽度代码,它应该可以正常工作。

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(999999, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    

    【讨论】:

      【解决方案6】:

      我知道它已经晚了,但如果有人有同样的问题。您可以通过创建自定义 ExpandableListView 并使用“MeasureSpec.EXACTLY”来解决它:

      public class CustomExpListView extends ExpandableListView{
          public CustomExpListView(Context context){
              super(context);
          }
          protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
              widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.EXACTLY);
              heightMeasureSpec = MeasureSpec.makeMeasureSpec(20000, MeasureSpec.AT_MOST);
              super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          }
      }
      

      希望这对任何人都有帮助。对我来说它的工作。

      【讨论】:

        【解决方案7】:

        添加到muhammadSalem 的答案。这就是我通过计算 expandableListView 的孩子的总高度来解决我的问题的方法。

         private fun getSubItemTotalHeight(groupPosition: Int): Int {
            val children: Int = mAdapter.getChildrenCount(groupPosition)
        
            val desiredWidth: Int = View.MeasureSpec.makeMeasureSpec(mExpandableListView.width,
                    View.MeasureSpec.UNSPECIFIED)
            var subItemTotalHeight = 0
            repeat(children) {
                val child = mAdapter.getChildView(groupPosition, it, true, null, null)
                child.layoutParams = ViewGroup.LayoutParams(
                        desiredWidth, View.MeasureSpec.UNSPECIFIED)
                child.measure(View.MeasureSpec.makeMeasureSpec(0,
                        View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
                        .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
                subItemTotalHeight += child.measuredHeight
            }
        
            val dividerCount = children - 1
            val dividerTotalCount = (dividerCount * mExpandableListView.dividerHeight).toFloat()
            showToast(mExpandableListView.dividerHeight.toString())
            val totalDividerPixels = TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP,
                    dividerTotalCount,
                    resources.displayMetrics
            )
            return subItemTotalHeight + totalDividerPixels.toInt()
        }
        

        需要注意的一点是,如果您为 expandableListview 添加了分隔线高度,则应该包括它的计算。我所做的是将 dp 中的总分隔线高度转换为像素并将其添加到 totalHeight 中。这解决了我遇到的剪辑问题。

        那么使用它就是:

            mExpandableListView.setOnGroupExpandListener { groupPosition ->
                    mExpandableListView.layoutParams.height += getSubItemTotalHeight(groupPosition)
                    mExpandableListView.requestLayout()
                }
                mExpandableListView.setOnGroupCollapseListener { groupPosition ->
                    mExpandableListView.layoutParams.height -= getSubItemTotalHeight(groupPosition)
                    mExpandableListView.requestLayout()
                }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-16
          • 1970-01-01
          • 1970-01-01
          • 2018-01-23
          相关资源
          最近更新 更多