3

I have an ImageView where I need to place a TextView on top of on a specific location on the ImageView like this drawingenter image description here

I have managed to do this, somewhat using the following xml:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/background"

        android:adjustViewBounds="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerInside"
        android:src="@drawable/imageBg"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="wrap_content"

        android:layout_height="wrap_content"
        android:text="Test text"

        android:textColor="#ff0000"

        android:layout_marginRight="200dp"
        android:layout_marginTop="205dp"


        app:layout_constraintLeft_toLeftOf="@id/background"
        app:layout_constraintRight_toRightOf="@id/background"
        app:layout_constraintTop_toTopOf="@id/background" />
        
</androidx.constraintlayout.widget.ConstraintLayout>

This works fine on my one emulator test device, but as I expected when trying on other emulator devices, it doesn't scale well across multiple devices running different resolutions etc. due to the fixed margin dp values.

How can I achieve this in the best possible way which would work across multiple devices and now that the TextView would be on the same position everytime? I know that I can make use of dimens.xml and use different margin values for different device dimensions there, but I don't believe this would be the best approach.

Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
Daniel Jørgensen
  • 1,183
  • 2
  • 19
  • 42

3 Answers3

3

I know that I can make use of dimens.xml and use different margin values for different device dimensions there, but I don't believe this would be the best approach.

You are correct, you can use guidelines like this to make sure that your layout will look the same on different screens:

<?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">

<ImageView
    android:id="@+id/imageView2"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:scaleType="fitXY"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHeight_percent="0.4"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintWidth_percent="0.8"
    tools:srcCompat="@tools:sample/backgrounds/scenic" />

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


<androidx.constraintlayout.widget.Guideline
    android:id="@+id/guideline3"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.45"/>

<TextView
    android:id="@+id/textView7"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/colorAccent"
    app:layout_constraintHeight_percent="0.1"
    app:layout_constraintWidth_percent="0.2"
    android:text="TextView"
    app:layout_constraintBottom_toTopOf="@+id/guideline2"
    app:layout_constraintEnd_toStartOf="@+id/guideline3" />

</androidx.constraintlayout.widget.ConstraintLayout>

It will look like this (the black arrows are the guidelines):

enter image description here

And now you have only 1 layout but it is a responsive layout - you don't need to create more for different devices.


Please notice that I don't have any fixed sizes on my views, I have created a fully responsive layout using percentage, for more info about the subject you can check my answer.

Tamir Abutbul
  • 7,301
  • 7
  • 25
  • 53
  • I went with this approach, as i think this is the most flexible way of achieving this. Never used Guidelines before, but they certainly are helpful for this! – Daniel Jørgensen Aug 01 '20 at 17:49
0

There is a Library https://github.com/intuit/sdp that provides a new size unit - sdp (scalable dp). This size unit scales with the screen size. It can help Android developers with supporting multiple screens. Here is a picture example of that enter image description here

Jyotish Biswas
  • 674
  • 5
  • 11
  • Took a look at it, and it doesn't seem to work that well tbh. When i try and place the textview its not placed at the same spot across my test emulator devices, and its enough movement for it to look bad. Furthermore i require it to be compatible all the way back to SDK 14, and this requires a minimum om 16 – Daniel Jørgensen Aug 01 '20 at 08:32
0

If the TextView is constrained to the image view at the top, bottom, start and end, then it will be positioned in the center of the ImageView. You can then use bias to position the TextView at a percentage position from the top and start of the ImageView. The TextView will maintain that relative position regardless of the screen size or orientation.

<androidx.constraintlayout.widget.ConstraintLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/background"

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="centerInside"
        android:src="@mipmap/ic_launcher"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Test text"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        android:textColor="#ff0000"
        app:layout_constraintBottom_toBottomOf="@+id/background"
        app:layout_constraintHorizontal_bias="0.25"
        app:layout_constraintLeft_toLeftOf="@id/background"
        app:layout_constraintRight_toRightOf="@id/background"
        app:layout_constraintTop_toTopOf="@id/background"
        app:layout_constraintVertical_bias="0.25" />

</androidx.constraintlayout.widget.ConstraintLayout>

This is what it looks like in Android Studio.

enter image description here

Cheticamp
  • 61,413
  • 10
  • 78
  • 131