Search code examples
androidxmlandroid-layoutandroid-coordinatorlayout

Middle of the button isn't placed to the bottom of another view


I have the following situation: I want to place my button to the bottom of ImageView (situation is the same as you can see in this question). I have the following xml layout:

<?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"
    tools:context=".ui.profile.ProfileFragment">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/coordinator_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/iv_background_avatar"
            android:layout_width="match_parent"
            android:layout_height="350dp"
            android:scaleType="centerCrop"
            android:src="@drawable/profile_background"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="ContentDescription" />


        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/btn_log_out"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_marginEnd="@dimen/base_margin"
            android:src="@drawable/logout"
            app:layout_anchor="@+id/iv_background_avatar"
            app:layout_anchorGravity="end|bottom" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/iv_avatar"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginTop="@dimen/base_margin"
        app:civ_border_color="#000000"
        app:civ_border_width="2dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:src="@tools:sample/avatars" />

    <TextView
        android:id="@+id/tv_login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/base_margin"
        android:layout_marginTop="@dimen/base_margin"
        android:layout_marginEnd="@dimen/base_margin"
        android:text="@string/login"
        android:textAlignment="center"
        app:layout_constraintTop_toBottomOf="@id/coordinator_layout" />

    <TextView
        android:id="@+id/tv_id"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/base_margin"
        android:layout_marginTop="@dimen/base_margin"
        android:layout_marginEnd="@dimen/base_margin"
        android:text="@string/id"
        android:textAlignment="center"
        app:layout_constraintTop_toBottomOf="@id/tv_login" />

    <TextView
        android:id="@+id/tv_email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/base_margin"
        android:layout_marginTop="@dimen/base_margin"
        android:layout_marginEnd="@dimen/base_margin"
        android:autoLink="email"
        android:clickable="true"
        android:focusable="true"
        android:text="@string/email"
        android:textAlignment="center"
        app:layout_constraintTop_toBottomOf="@id/tv_id" />


</androidx.constraintlayout.widget.ConstraintLayout>

As in the question, which is higher, I added Coordinator Layout, but it allows me only to place FAB in the corners and middles of the sides of avatar while I need to place it to the bottom|end corner of background iv and I specified it in attribute.But unfortunately FAB isn't placed as it need to be (sorry for such a background color):

enter image description here

So, how can I solve this problem?


Solution

  • You can use ConstraintLayout to achieve this "view over view" look.

    Here is an example using ConstraintLayout without using fixed sizes:

    <?xml version="1.0" encoding="utf-8"?>
    
    
    <android.support.constraint.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"
      android:orientation="vertical">
    
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:text="FAB"
        app:layout_constraintBottom_toBottomOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />
    
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars[7]" />
    
    </android.support.constraint.ConstraintLayout>
    

    And it will look like this:

    enter image description here

    And now if you want to change the position of your button horizontally all you need to do is change one constraint and you got it.


    For example - if you want your button to be aligned to the right side you can do something like this:

    <?xml version="1.0" encoding="utf-8"?>
    
    
    <android.support.constraint.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"
      android:orientation="vertical"
     >
    
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="FAB"
        app:layout_constraintBottom_toBottomOf="@+id/imageView"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />
    
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars[7]" />
    
    </android.support.constraint.ConstraintLayout>
    

    And it will look like this:

    enter image description here


    Please notice:

    Different phones got different screen size, in your layout you are using fixed-size on your views and the result is that what may look good on one screen will not look good on another screen.

    In my examples, I was using wrap_content instead of fixed sizes.

    I know that using wrap_content is not ideal as well for responsive layout, if you want your layout to be responsive to all screen sizes I can recommend to use Guidelines