【问题标题】:Android staticlayout height is not consistent which causes weird rendering bugAndroid静态布局高度不一致导致奇怪的渲染错误
【发布时间】:2016-07-24 23:48:23
【问题描述】:

我最近创建了一个自定义视图来测试 StaticLayout.getHeight() 方法,我发现它确实不一致。在我解释错误之前,让我先写下代码:

这是我的 MainActivity.java

   package com.ayto.android.test;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RelativeLayout mainParent = (RelativeLayout) findViewById(R.id.mainActivity);
        RelativeLayout childRelativeLayout = (RelativeLayout) getLayoutInflater().inflate(R.layout.activity_test3,null);
        noteLayout testNoteLayout = new noteLayout(this);
        testNoteLayout.addView(childRelativeLayout);
        mainParent.addView(testNoteLayout);
    }

}

这是我的自定义布局:

package com.ayto.android.test;
import android.content.Context;
import android.graphics.RectF;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
public class noteLayout extends ViewGroup {
    public noteLayout(Context activityContext)
    {
        super(activityContext);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        RelativeLayout mainParent = (RelativeLayout) getParent();
        for (int i = 0; i < getChildCount(); i++) {
            RelativeLayout child = (RelativeLayout) getChildAt(i);
            child.measure(MeasureSpec.makeMeasureSpec((mainParent.getWidth() / 2), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) (child.getChildAt(0).getMeasuredHeight()), MeasureSpec.EXACTLY));
        }
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int numberOfChild = getChildCount();
        for (int i = 0;i<numberOfChild;i++){
            View childView = getChildAt(i);
            float childHeight = (float) childView.getMeasuredHeight();
            float childWidth = (float) childView.getMeasuredWidth();
            RectF rect = new RectF();
            rect.bottom = childHeight;
            rect.top = 20;
            rect.left = 20;
            rect.right = childWidth+20;
            childView.layout((int) rect.left, (int) rect.top, (int) rect.right, (int) rect.bottom);
        }
    }
}

这是我的activity_main.xml:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
    android:id="@+id/mainActivity">

    />
</RelativeLayout>

这是我膨胀的activity_test3.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#EF5350">

    <com.ayto.android.test.titleTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/titleTextView"
        android:textSize="18sp"
        android:text="sadasdas das dasd asd as dasdasdasdsad sad asd asd asdasdasdsa sa zvczz xczxczxczx sadasasdsadsadsaasd "

        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</RelativeLayout>

现在我的问题是,在我的自定义布局中,我告诉它的孩子哪个是 relativeLayout 来衡量自己。 relativeLayout 基本上是来自 activity_test3.xml 的 relativeLayout,其中包含我创建的名为 titleTextView 的自定义视图。在这个视图中,我重写了 onMeasure() 方法并使用 staticLayout 来获取要设置的高度。然后我的 relativeLayout 是 titleTextView 的父级,它基本上是衡量自己的,并且具有来自其子级的约束,即 titleTextView(请参阅上面的代码以澄清任何混淆,因为它真的很难解释)。

我的问题是 relativeLayout 的高度小于所需的高度,因此它会夹住孩子。这是一些图片:

此外,您可以看到,不同设备的高度确实不一致,我认为 staticLayout.getHeight() 假设返回一致的像素大小。我不太确定如何解决它并需要帮助。

注意:我尝试将像素大小返回的 staticLayout.getHeight 乘以密度,它变得太大而无法完全适合其中的文本。

【问题讨论】:

    标签: java android


    【解决方案1】:

    在您的自定义布局onLayout 方法中将顶部(在您的情况下为 rect.top = 20)偏移量添加到 rect.bottom:

    protected void onLayout(boolean changed, int l, int t, int r, int b) {
            .
            .
            .
            rect.bottom = childHeight + 20;
    

    高度不一致是由于设备的像素密度不同造成的。一些相关信息可以在What is the difference between getWidth/Height() and getMeasuredWidth/Height() in Android SDK?找到

    【讨论】:

    • 您好,感谢您的回答。我也是这么想的。不一致是由于设备上不同的像素密度造成的,但奇怪的是,当我将像素返回乘以 staticLayout.height() 乘以密度时,第一张图像中的设备与文本很好地吻合。然而,第二个设备变得如此之大,以至于它对于里面的文本来说是多余的。我想我上面提到过我将它乘以密度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    相关资源
    最近更新 更多