我创建了一些基于 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" />
正如您在评论中所述:“我在布局检查器中注意到的唯一奇怪的事情是,对于 CustomSwitchCompat ,未设置 id,但这怎么可能?” 这是未设置 id 的线索.
视图的 id 是从必须解析的属性中获取的。这是在 ConstraintLayout 构造函数之一中完成的,即 public ConstraintLayout(@NonNull Context context, @Nullable AttributeSet attrs)。
在您的实现中,您实际上并不直接解析 id,而是希望将这项工作留给 ConstraintLayout 的超类,如上所述。不幸的是,您调用的是
super(context)
而不是 super(context, attrs)
,因此 id(以及从属性中获取的所有其他属性根本不会被获取。
调用 super(context, attrs) 来更正您的代码。