ConstraintLayout 自定义视图拒绝用作约束

问题描述 投票:0回答:1

我创建了一些基于 ContraintLayout 的自定义视图,它基本上是文本视图和其他一些组件的配对。

EditTextCompat 和 SwitchCompat。 两者的创建方式基本上相同,但只有“交互”部分不同。

当我使用 CustomEditTextCompat 并将其用作layout_constraintTop_toBottomOf =“CustomEditTextCompat”时,它按预期工作。 但是当我做同样的事情并尝试使用 CustomSwitchCompat 作为约束时,视图就会跳到顶部。

有什么建议吗?

自定义_switch_compat.xml

<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:background="@color/black">

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/centerLeft_line"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.49" />

<androidx.constraintlayout.widget.Guideline
    android:id="@+id/centerRight_line"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.51" />

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/switchTextLabel"
    style="@style/ColorAndFontTheme"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="13dp"
    android:layout_marginEnd="8dp"
    app:layout_constraintEnd_toStartOf="@+id/centerLeft_line"
    app:layout_constraintTop_toTopOf="parent"
    tools:text="Label" />

<androidx.appcompat.widget.SwitchCompat
    android:id="@+id/switchValue"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:checked="false"
    android:theme="@style/menuSwitchTheme"
    app:layout_constraintBottom_toBottomOf="@+id/switchTextLabel"
    app:layout_constraintStart_toEndOf="@+id/centerRight_line"
    app:layout_constraintTop_toTopOf="@+id/switchTextLabel" />
 </androidx.constraintlayout.widget.ConstraintLayout>

CustomSwitchCompat.java

public class CustomSwitchCompat extends ConstraintLayout {
private TextView label;
private SwitchCompat switchCompat;

public CustomSwitchCompat(Context context, AttributeSet attrs) {
    super(context);
    init(context, attrs);
}

private void init(Context context, AttributeSet attrs) {
    LayoutInflater.from(context).inflate(R.layout.custom_switch_compat, this, true);
    label = findViewById(R.id.switchTextLabel);
    switchCompat = findViewById(R.id.switchValue);
    TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CustomSwitchCompat);


    String labelText = attributes.getString(R.styleable.CustomSwitchCompat_switchLabelText);
    label.setText(labelText);
    // Additional attributes such as onText and offText can be set here
    attributes.recycle();
}
}

自定义_编辑_文本_compat.xml

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:background="@color/black">

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/centerLeft_line"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.49" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/centerRight_line"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.51" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/textLabel"
        style="@style/ColorAndFontTheme"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="18dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toStartOf="@+id/centerLeft_line"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Label" />

    <androidx.appcompat.widget.AppCompatEditText
        android:id="@+id/editInput"
        style="@style/ColorAndFontTheme"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="3dp"
        android:textColorHint="@color/gray"
        app:layout_constraintBottom_toBottomOf="@+id/textLabel"
        app:layout_constraintStart_toStartOf="@+id/centerRight_line"
        app:layout_constraintTop_toTopOf="@id/textLabel"
        tools:text="Editbox" />

</androidx.constraintlayout.widget.ConstraintLayout>

自定义编辑文本兼容.java

public class CustomEditTextCompat extends ConstraintLayout {
    protected AppCompatEditText editInput;
    private AppCompatTextView textLabel;

    public CustomEditTextCompat(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        LayoutInflater.from(context).inflate(R.layout.custom_edit_text_compat, this, true);

        textLabel = findViewById(R.id.textLabel);
        editInput = findViewById(R.id.editInput);

        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CustomEditTextCompat);
        String labelText = attributes.getString(R.styleable.CustomEditTextCompat_labelText);
        String hintText = attributes.getString(R.styleable.CustomEditTextCompat_hintText);

        textLabel.setText(labelText);
        editInput.setHint(hintText);

        attributes.recycle();
    }

    public String getEditTextValue() {
        return editInput.getText().toString();
    }

    public void setLabelText(String text) {
        textLabel.setText(text);
    }

    public void setHintText(String hint) {
        editInput.setHint(hint);
    }
}

用途:

<com..menuFragments.components.CustomEditTextCompat
        android:id="@+id/custom_attacks_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:hintText="Cool fire wave"
        app:labelText="Attack Name"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com..menuFragments.components.CustomSwitchCompat
        android:id="@+id/custom_attacks_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/custom_attacks_name"
        app:switchLabelText="Finish when done" />

    <com..menuFragments.components.CustomEditTextCompat
        android:id="@+id/custom_attacks_box_width"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:hintText="Default"
        app:labelText="Box width"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/custom_attacks_switch" />
java android android-constraintlayout
1个回答
0
投票

正如您在评论中所述:“我在布局检查器中注意到的唯一奇怪的事情是,对于 CustomSwitchCompat ,未设置 id,但这怎么可能?” 这是未设置 id 的线索.

视图的 id 是从必须解析的属性中获取的。这是在 ConstraintLayout 构造函数之一中完成的,即 public ConstraintLayout(@NonNull Context context, @Nullable AttributeSet attrs)

在您的实现中,您实际上并不直接解析 id,而是希望将这项工作留给 ConstraintLayout 的超类,如上所述。不幸的是,您调用的是

super(context)
而不是
super(context, attrs)
,因此 id(以及从属性中获取的所有其他属性根本不会被获取。

调用 super(context, attrs) 来更正您的代码。

© www.soinside.com 2019 - 2024. All rights reserved.