为什么 getMeasuredHeight() 没有返回准确的值?

Why is getMeasuredHeight() not returning the exact value?

我想通过查找布局的高度来设置 dialog fragment 的高度。

在视图中是 five heights

我无法使用 getHeight() 获取布局的高度。

我为此使用了 getMeasuredHeight()。 (getHeight() 仅 returned 0。)

但是 getMeasuredHeight() 似乎也不是 return 确切的值。

我尝试将其设置为此布局的 5 倍高度,但实际高度为 设置的高度少于 5 个。 (请参考照片)

为什么会这样?

writing_comment_xml

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".fragment.WritingCommentDialogFragment">
    <EditText
        android:id="@+id/comment_edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:gravity="center_vertical"
        android:drawableLeft="@drawable/ic_bullet_point"
        android:drawablePadding="5dp"
        android:layout_marginHorizontal="10dp"
        android:background="@null"
        android:textSize="15sp"
        android:inputType="text"
        android:maxLines="1"
        android:maxLength="22"
        android:imeOptions="actionNext"
       app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    </EditText>
</androidx.constraintlayout.widget.ConstraintLayout>

已编辑

DialogFragment.java

public class WritingCommentDialogFragment extends DialogFragment implements CommentModel.EditInputListener {
    OnBackPressedCallback callback;

    LinearLayout commentContainer; // input layout
    private final List<Comment> comments = new ArrayList<>();
    private LayoutInflater layoutInflater;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_writing_comment_dialog, container, false);
        bindViews(view);
        addCommentItem();
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        setDialogSize();
    }

    private void bindViews(View v) {
        commentContainer = v.findViewById(R.id.container);
        layoutInflater = LayoutInflater.from(getContext());
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.setCanceledOnTouchOutside(false);
        return dialog;
    }
    
    private void setDialogSize() {
        View v = LayoutInflater.from(getContext()).inflate(R.layout.writing_comment_item, null, false);

        new Handler().post(() -> {
            int size = v.getHeight() * 5;
            getDialog().getWindow().setLayout(1000, size);
        });
    }
}

已添加

布局检查器

fragment_writing_comment_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".fragment.WritingCommentDialogFragment">
    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

我认为潜在的问题是对话框将滑入另一个名为 decorViewViewGroup 中,它有一些填充缩小了对话。这是您的代码的简化版本,它适当地调整了对话框 window 的大小,因此对话框是您想要的大小。代码中的注释解释得更多一些。

public class WritingCommentDialogFragment extends DialogFragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        setWindowSize();
        View view = inflater.inflate(R.layout.fragment_writing_comment_dialog, container, false);
        return view;
    }

    private void setWindowSize() {
        int[] widthHeight = getDialogSize();
        Window window = getDialog().getWindow();
        // Our dialog will go inside the decorView which may have padding. So, the window has
        // to be the width of our dialog plus the padding.
        View decorView = window.getDecorView();
        int horizontalPadding = decorView.getPaddingStart() + decorView.getPaddingEnd();
        int verticalPadding = decorView.getPaddingTop() + decorView.getPaddingBottom();
        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        lp.copyFrom(window.getAttributes());
        lp.width = widthHeight[0] + horizontalPadding;
        lp.height = widthHeight[1] + verticalPadding;
        window.setAttributes(lp);
    }

    private int[] getDialogSize() {
        View v = LayoutInflater.from(getContext())
                .inflate(R.layout.writing_comment_item,
                        (ConstraintLayout) getView(),   // This is the parent.
                        false);             // Don't attach the view to the parent.

        // Measure one of the five child views to be added. The width is match_parent and the
        // height is wrap_content.
        v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        int height = v.getMeasuredHeight();
        return new int[]{DIALOG_WIDTH, height * 5};
    }

    private static final int DIALOG_WIDTH = 1000; // Maybe should be dp?
}