Android 确定视图的测量高度的精确方法,即使在视图从“消失”变为“可见”之前

Android 确定视图的测量高度的精确方法,即使在视图从“消失”变为“可见”之前,android,Android,目前,我有一个这样的布局。它包含 标题文本视图和价格文本视图,始终可见 描述文本视图,可以是可见的或消失的,具体取决于展开或折叠 正在折叠(在应用程序启动期间) 展开(当用户点击时) 我想有一些漂亮的动画围绕它。所以,我提到 其中一个关键因素是,即使在描述文本视图可见之前,也要知道它的确切高度 但是,我实现了几种类型的代码。它们不准确 // v is description text view. v.measure(LayoutParams.FILL_PARENT, LayoutPara

目前,我有一个这样的布局。它包含

  • 标题文本视图和价格文本视图,始终可见
  • 描述文本视图,可以是可见的或消失的,具体取决于展开或折叠
正在折叠(在应用程序启动期间)

展开(当用户点击时)

我想有一些漂亮的动画围绕它。所以,我提到

其中一个关键因素是,即使在描述文本视图可见之前,也要知道它的确切高度

但是,我实现了几种类型的代码。它们不准确

// v is description text view.
v.measure(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
final int targtetHeight = v.getMeasuredHeight();

这将返回值32。(正确的测量高度假定为92)。这是文本第一行的高度。这结束了我的动画结束于

我想知道,在视图从消失变为可见之前,确定视图测量高度的正确方法是什么

我的布局代码如下:

        <LinearLayout
            android:clickable="true"
            android:id="@+id/chart_linear_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:background="@drawable/dummy"
            android:orientation="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                android:orientation="horizontal">
                <TextView
                    android:layout_width="0dp"
                    android:width="0dp"
                    android:layout_weight="0.6"
                    android:layout_height="match_parent"
                    android:gravity="left"
                    android:textSize="20sp" 
                    android:textColor="#ff000000"
                    android:text="Summary chart" />
                <TextView
                    android:id="@+id/chart_price_text_view"
                    android:layout_width="0dp"
                    android:width="0dp"
                    android:layout_weight="0.4"
                    android:layout_height="match_parent"
                    android:gravity="right"
                    android:textSize="20sp" 
                    android:textColor="#ffF76D3C"
                    android:text="$2.99" />

            </LinearLayout>
            <TextView
                android:visibility="gone"
                android:id="@+id/chart_description_text_view"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:layout_marginBottom="10dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"         
                android:text="@string/currency_exchange_description"
                android:textColor="#ff626262"
                android:textSize="15sp" />                 
        </LinearLayout>

您的第二个代码片段几乎是正确的,但您需要指定像素大小-而不是
填充父项/匹配父项
。这应该起作用:

v.measure(MeasureSpec.makeMeasureSpec(parentView.getWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(MAX_HEIGHT, MeasureSpec.AT_MOST));
final int targetHeight = v.getMeasuredHeight();
您需要对
v
是其子视图的视图组进行引用,以获取其宽度,并定义
MAX\u HEIGHT
(或者使用父视图的高度?)


此外,您应该将水平线性布局内的两个文本视图的高度参数更改为
wrap\u content
,因为在此处使用
match\u parent
可能会导致问题。LinearLayout设置为wrap_内容,但两个孩子没有指定高度。

我为我的手风琴组件完成了这项工作。我面临着完全相同的问题,我的手风琴需要扩展到“目的地”高度,也就是扩展后的高度。 这将返回正确的高度:

/***
 * This function returns the actual height the layout. The getHeight() function returns the current height which might be zero if
 * the layout's visibility is GONE
 * @param layout
 * @return
 */
public static int getFullHeight(ViewGroup layout) {
    int specWidth = View.MeasureSpec.makeMeasureSpec(0 /* any */, View.MeasureSpec.UNSPECIFIED);
    int specHeight = View.MeasureSpec.makeMeasureSpec(0 /* any */, View.MeasureSpec.UNSPECIFIED);


    layout.measure(specWidth,specHeight);
    int totalHeight = 0;//layout.getMeasuredHeight();
    int initialVisibility = layout.getVisibility();
    layout.setVisibility(View.VISIBLE);
    int numberOfChildren = layout.getChildCount();
    for(int i = 0;i<numberOfChildren;i++) {
        View child = layout.getChildAt(i);
        if(child instanceof ViewGroup) {
            totalHeight+=getFullHeight((ViewGroup)child);
        }else {
            int desiredWidth = View.MeasureSpec.makeMeasureSpec(layout.getWidth(),
                    View.MeasureSpec.AT_MOST);
            child.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight+=child.getMeasuredHeight();
        }

    }
    layout.setVisibility(initialVisibility);
    return totalHeight;
}
/***
*此函数用于返回布局的实际高度。函数的作用是:返回当前高度,如果
*布局的可见性消失
*@param布局
*@返回
*/
公共静态整型getFullHeight(视图组布局){
int specWidth=View.MeasureSpec.makeMeasureSpec(0/*any*/,View.MeasureSpec.UNSPECIFIED);
int specHeight=View.MeasureSpec.makeMeasureSpec(0/*any*/,View.MeasureSpec.UNSPECIFIED);
布局。测量(规格宽度、规格高度);
int totalHeight=0;//layout.getMeasuredHeight();
int initialVisibility=layout.getVisibility();
布局.设置可见性(视图.可见);
int numberOfChildren=layout.getChildCount();

对于(int i=0;除非您知道文本将占用多少行,否则在测量之前没有办法对其进行测量。一种简单的方法可能是将它们全部设置为“不可见”,而不是在开始时测量,然后在随后立即测量它们。如果您只有几个视图,这可能不会引起用户的注意你们有什么解释为什么多重包装线不起作用吗?我认为v.measure(…应该起作用(尽管它现在不起作用)不确定,但我认为这只是衡量它对
文本视图
的总体预期。它可能还没有意识到它需要多行代码。这对我也有帮助,但在我的情况下,这并不是全部。这就是我最终解决问题的方式:
/***
 * This function returns the actual height the layout. The getHeight() function returns the current height which might be zero if
 * the layout's visibility is GONE
 * @param layout
 * @return
 */
public static int getFullHeight(ViewGroup layout) {
    int specWidth = View.MeasureSpec.makeMeasureSpec(0 /* any */, View.MeasureSpec.UNSPECIFIED);
    int specHeight = View.MeasureSpec.makeMeasureSpec(0 /* any */, View.MeasureSpec.UNSPECIFIED);


    layout.measure(specWidth,specHeight);
    int totalHeight = 0;//layout.getMeasuredHeight();
    int initialVisibility = layout.getVisibility();
    layout.setVisibility(View.VISIBLE);
    int numberOfChildren = layout.getChildCount();
    for(int i = 0;i<numberOfChildren;i++) {
        View child = layout.getChildAt(i);
        if(child instanceof ViewGroup) {
            totalHeight+=getFullHeight((ViewGroup)child);
        }else {
            int desiredWidth = View.MeasureSpec.makeMeasureSpec(layout.getWidth(),
                    View.MeasureSpec.AT_MOST);
            child.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
            totalHeight+=child.getMeasuredHeight();
        }

    }
    layout.setVisibility(initialVisibility);
    return totalHeight;
}