I have a ConstraintLayout containing two custom text views. When I try using a percentage it causes the app to crash with a complaint about a null anchor. However the anchors seem valid to me.
I've been through a process of trial and error and no attempt has avoided the crash (for example removing app:layout_constraintEnd_toStartOf="@ id/b"
or setting it to app:layout_constraintEnd_toEndOf="parent"
)
The Layout
<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="match_parent">
<com.custom.TextInputView
android:id="@ id/a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@ id/b"
app:layout_constraintTop_toBottomOf="@id/c_notshown_in_example"
app:layout_constraintGuide_percent="0.45" />
<com.custom.TextInputView
android:id="@ id/b"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/u2"
android:layout_marginEnd="@dimen/u2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/a"
app:layout_constraintTop_toTopOf="@id/a" />
The Crash:
java.lang.NullPointerException: Attempt to invoke virtual method 'int androidx.constraintlayout.core.widgets.ConstraintAnchor.getFinalValue()' on a null object reference at androidx.constraintlayout.core.widgets.analyzer.Direct.horizontalSolvingPass(Direct.java:328) at androidx.constraintlayout.core.widgets.analyzer.Direct.solvingPass(Direct.java:254) at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.layout(ConstraintWidgetContainer.java:693) at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solveLinearSystem(BasicMeasure.java:160) at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:291) at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:120) a at
What horizontal constraints does the percentage usage require? (since it fails at horizontalSolvingPass)
CodePudding user response:
The idea will be to wire the ConstraintLayout
to the Guideline
and everything beside that (e.g. TextView etc.) to the ConstraintLayout
for a responsive design.
My example shows it with 2 TextView
that are exactly 80% vertically for instance and 45% and 55% in width
(app:layout_constraintGuide_percent="0.45"
). Important is to set the TextViews
width
and height
to 0dp
and to attach to the Guideline
:
<?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="match_parent">
<!-- Vertical Guideline for Text1 (here e.g. 45%) -->
<androidx.constraintlayout.widget.Guideline
android:id="@ id/vertical_guideline1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.45" />
<!-- Horizontal Guideline for both Texts (here e.g. 80%)-->
<androidx.constraintlayout.widget.Guideline
android:id="@ id/horizontal_guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.8" />
<!-- TextView1 in Blue -->
<TextView
android:id="@ id/textView1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#2962FF"
android:textColor="@color/white"
app:layout_constraintBottom_toTopOf="@ id/horizontal_guideline"
app:layout_constraintEnd_toStartOf="@ id/vertical_guideline1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView1 in Blue 45%" />
<!-- TextView2 in Orange -->
<TextView
android:id="@ id/textView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#FF6D00"
android:textColor="@color/white"
app:layout_constraintBottom_toTopOf="@ id/horizontal_guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@ id/vertical_guideline1"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView2 in Orange 55%" />
</androidx.constraintlayout.widget.ConstraintLayout>
RESULT:
CodePudding user response:
There are a few problems with the constraints on your @ id/a
view:
- The correct percentage constraint is
app:layout_constraintWidth_percent
- You should use
0dp
for the width when using percents - You should constrain both sides of the view to the parent (to define the width is a percentage of)
Once you've done that, you will also have to add bias to the view in order to position it on the far left of the screen:
app:layout_constraintHorizontal_bias="0"
Altogether, your first view should look like this:
<com.custom.TextInputView
android:id="@ id/a"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/c_notshown_in_example"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintWidth_percent="0.45"
app:layout_constraintHorizontal_bias="0" />