ConstraintLayout 不当行为

ConstraintLayout misbehaviour

这是我的对话,

public class TestDialog extends DialogFragment {

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.test_dialog, container, false);
    }
}

当我使用 RelativeLayout 进行如下设计时,

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

    <TextView
        android:id="@+id/textTitle"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp48"
        android:layout_alignParentTop="true"
        android:fontFamily="@font/trebuchet"
        android:gravity="center"
        android:text="Test Dialog"
        android:textColor="?attr/colorAccent"
        android:textSize="18sp" />

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textTitle"
        android:src="@drawable/ic_baseline_public_24px"
        android:tint="@color/black" />

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textTitle"
        android:layout_marginStart="5dp"
        android:layout_toEndOf="@+id/icon"
        android:fontFamily="@font/trebuchet"
        android:text="This is very long text, This is very long text, This is very long text" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/imageView_close"
        style="@style/Widget.MaterialComponents.Button.OutlinedButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/text"
        android:layout_centerHorizontal="true"
        android:contentDescription="@string/close"
        android:src="@drawable/ic_baseline_close_24dx"
        android:text="@string/cancel" />
</RelativeLayout>

我得到了这个输出。

但是当我在如下设计中使用 ConstraintLayout 时,

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textTitle"
        android:layout_width="0dp"
        android:layout_height="@dimen/dp48"
        android:fontFamily="@font/trebuchet"
        android:gravity="center"
        android:text="Test Dialog"
        android:textColor="?attr/colorAccent"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textTitle"
        android:src="@drawable/ic_baseline_public_24px"
        android:tint="@color/black"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textTitle" />

    <TextView
        android:id="@+id/text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="5dp"
        android:fontFamily="@font/trebuchet"
        android:text="This is very long text, This is very long text, This is very long text"
        app:layout_constraintStart_toEndOf="@+id/icon"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textTitle" />

    <com.google.android.material.button.MaterialButton
        android:id="@+id/imageView_close"
        style="@style/Widget.MaterialComponents.Button.OutlinedButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/close"
        android:src="@drawable/ic_baseline_close_24dx"
        android:text="@string/cancel"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text" />
</androidx.constraintlayout.widget.ConstraintLayout>

我得到以下输出。

我不知道为什么会出现这种奇怪的行为。只有在对话中我才会有这种行为。

如果我在约束布局中遗漏了什么,请让我知道的朋友,我会自己纠正。

我认为问题出在您的 ConstraintLayout 标记中 android:layout_width="match_parent"。由于 Dialog 没有固定宽度,因此使用 match_parent 将不起作用。也许你可以设置一个固定宽度,或者最小宽度。

您只需将主题设置为您的对话框即可。

 @Override
    public int getTheme() {
        return R.style.dialog;
    }

风格

<style name="dialog" parent="android:Theme.Dialog">
        <item name="android:windowBackground">@drawable/radius</item>
        <item name="android:windowMinWidthMajor">80%</item>
        <item name="android:windowMinWidthMinor">85%</item>
        <item name="android:windowNoTitle">true</item>
    </style>

radius.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white" />
    <corners android:radius="10dp" />
    <padding
        android:bottom="8dp"
        android:left="8dp"
        android:right="8dp"
        android:top="8dp" />
</shape>

首先,这不是 ConstraintLayout,而是您如何实施 Dialog 本身。这是一个建议,根据 Dialog Documentation:

The Dialog class is the base class for dialogs, but you should avoid instantiating Dialog directly. Instead, use one of the following subclasses:

AlertDialog
A dialog that can show a title, up to three buttons, a list of selectable items, or a custom layout.

DatePickerDialog or TimePickerDialog
A dialog with a pre-defined UI that allows the user to select a date or time.

所以基本上你会使用 setView api:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
    // Setting my layout here
    builder.setView(R.layout.my_layout);
    builder.setPositiveButton(/* My Methods */)
           .setNegativeButton(/* My Methods */);
    return builder.create();
}

Creating a Custom Layout documentation 中了解它。如果您想要更多自定义,请在 values > styles.xml 中创建一个自定义主题,它可以在整个应用程序中使用,或者只需将其与构建器一起设置,例如:

new AlertDialog.Builder(requireActivity(), R.style.My_Alert_Dialog_Theme);