简体   繁体   中英

Percentage based guideline in ConstraintLayout moves when view is made visible, android

Context : I am making part of a sign-up page. Once the user types in their email, they tap continue and type in their password. Tapping continue triggers Kotlin code that sets the password view's visibility to VISIBLE.

The top TextView is constrained to a guideline with the attribute "app:layout_constraintGuide_percent=".3". I expect this to mean that it will never move.

Problem : When the password input view is set to visible by the Kotlin code, all of the views shift downwards, inexplicably. It is as if the 30% becomes 35%, although of course that is not the case.

I have checked out this post and tried to use bias, but it generates the exact same behaviour.

fragment_sign_up_email.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/white"
        android:padding="@dimen/sign_up_in_outer_padding"
        android:animateLayoutChanges="true"
        tools:context=".SignUpEmailFragment">


        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="@font/lato_bold"
            android:text="@string/xxxx"
            android:textSize="@dimen/title_font_size"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline3"/>

        <TextView
            android:id="@+id/textView5"
            android:layout_width="20dp"
            android:layout_height="wrap_content"
            android:fontFamily="@font/lato"
            android:text="@string/or"
            android:textSize="@dimen/subtitle_font_size"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView4" />

        <TextView
            android:id="@+id/sign_in_button_on_sign_up_screen"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="@font/lato_bold"
            android:text="@string/sign_in"
            android:textColor="@color/main_green"
            android:textSize="@dimen/subtitle_font_size"
            app:layout_constraintStart_toEndOf="@+id/textView5"
            app:layout_constraintTop_toBottomOf="@+id/textView4"/>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/email_field_sign_up"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:hint="@string/email_hint"
            app:boxBackgroundColor="@color/white"
            app:errorEnabled="true"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/sign_in_button_on_sign_up_screen"
            app:startIconDrawable="@drawable/common_google_signin_btn_icon_light">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/email_input_sign_up"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/password_field_sign_up"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/password_hint"
            app:boxBackgroundColor="@color/white"
            android:visibility="gone"
            app:errorEnabled="true"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/email_field_sign_up"
            app:startIconDrawable="@drawable/common_google_signin_btn_icon_light">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/password_input_sign_up"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </com.google.android.material.textfield.TextInputLayout>

        <Button
            android:id="@+id/sign_up_email_pass_continue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/continue_text"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/password_field_sign_up" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent=".3" />


    </androidx.constraintlayout.widget.ConstraintLayout>



</layout>

SignUpEmailFragment.kt:

package com.example.xxxxx

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import com.example.xxxxx.databinding.FragmentSignUpEmailBinding

/**
 * Fragment that handles the sign in procedure
 */
class SignUpEmailFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
        val binding: FragmentSignUpEmailBinding = DataBindingUtil.inflate(inflater,R.layout.fragment_sign_up_email  , container, false)

        binding.signUpEmailPassContinue.setOnClickListener{view: View ->
            continueIsClicked(binding)
        }

        return binding.root
    }


    private fun continueIsClicked(binding: FragmentSignUpEmailBinding) {
        if(emailIsValid(binding)){
                binding.passwordFieldSignUp.setVisibility(View.VISIBLE);
                if(passwordIsValid(binding)){
                    //TODO navigate to next page
                }
        }
    }

    private fun passwordIsValid(binding: FragmentSignUpEmailBinding): Boolean {
        //TODO implement
        return true
    }

    private fun emailIsValid(binding: FragmentSignUpEmailBinding): Boolean {
        //TODO implement
        return true
    }

    companion object {
        fun newInstance() = SignUpEmailFragment()
    }

}

Before click: screenshot 1

After click: screenshot 2

I figured it out.

The androidx.fragment.app.FragmentContainerView in which this Fragment appears had the attribute android:layout_height="wrap_content" . I changed it to android:layout_height="match_parent" and the it worked correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM