Home > Back-end >  What other constraints does layout_constraintGuide_percent require
What other constraints does layout_constraintGuide_percent require

Time:12-04

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:

Now you have 45% and 55% in width

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" />
  • Related