1

I am making an android app for which i need the 3 image buttons containing the location pointers to be placed along the road in the background in the positions shown in the screenshot. Unfortunately the image buttons change their positions on different screen sizes. Any help is appreciated.

enter image description here

This following is my XML code. For now for the sake of the screenshot i have manually given values to the margin of the buttons and also because i don't know any other way of doing it.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.HomeFragment">
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_image"
    android:orientation="vertical">
    <LinearLayout
        android:id="@+id/ll1"
        android:gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="85dp"
        android:layout_marginStart="85dp"
        android:layout_marginTop="200dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/potheri_button_text"
            android:textStyle="bold"
            android:textColor="@android:color/black"
            android:layout_marginBottom="5dp"/>
        <ImageButton
            android:id="@+id/potheri_button"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="#00000000"
            android:scaleType="centerInside"
            android:src="@drawable/location_pointer" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/ll2"
        android:gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="300dp"
        android:layout_marginStart="300dp"
        android:layout_marginTop="200dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/srm_button_text"
            android:textStyle="bold"
            android:textColor="@android:color/black"
            android:layout_marginBottom="5dp"/>
        <ImageButton
            android:id="@+id/srm_button"
            android:textSize="20sp"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:scaleType="centerInside"
            android:background="#00000000"
            android:src="@drawable/location_pointer" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/ll3"
        android:gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="170dp"
        android:layout_marginStart="170dp"
        android:layout_marginTop="435dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/guduvancheri_button_text"
            android:textStyle="bold"
            android:textColor="@android:color/black"
            android:layout_marginBottom="5dp"/>
        <ImageButton
            android:id="@+id/guduvancheri_button"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="#00000000"
            android:scaleType="centerInside"
            android:src="@drawable/location_pointer"
            android:text="@string/guduvancheri_button_text"/>
    </LinearLayout>
</RelativeLayout>

Neeraj Athalye
  • 508
  • 5
  • 26
  • Add your XML layout code, Lets look what made the image displacement. – W4R10CK Feb 02 '17 at 16:40
  • Its either you use dimens.xml for different dimensions or you assign those location images in the image itself and adjust the Scale Type of the ImageView – Mike Feb 02 '17 at 16:48
  • @W4R10CK i have updated my post with the XML code. – Neeraj Athalye Feb 02 '17 at 16:57
  • @Mike To use dimens.xml wont i need multiple dimens.xml files for multiple device dimensions? – Neeraj Athalye Feb 02 '17 at 16:57
  • @Neeraj yes, you would need multiple dimens.xml if thats the process you want but looking at your code, it seems that you placed the image as a background for relativelayout, That is not recommended as the layout can stretch the image depending on the size of the phone. I would recommend you attach the location pins on the image itself then place it on an ImageView with a proper Scale Type – Mike Feb 02 '17 at 17:00
  • @Mike If i do add the the location pins to the image then how will i register the touches on the pins separately? – Neeraj Athalye Feb 02 '17 at 17:02
  • @Mike To clarify, each of these pins opens the next fragment with different arguments – Neeraj Athalye Feb 02 '17 at 17:04
  • @Neeraj what I would suggest is on the onclick of the said ImageView, just create an if else statement provided with the X / Y axis of the said pins are located would trigger different opening / arguments of fragment. – Mike Feb 02 '17 at 17:10
  • @Mike could you tell me how to do that in a bit more detail? I'm afraid i'm not experienced enough to do that. – Neeraj Athalye Feb 02 '17 at 17:12
  • @Neeraj in your onclick you can try something like int[] location = new int[2]; imageView.getLocationOnScreen(location); int x = location[0]; int y = location[1]; now depending on the x and y position if it s near the left / right or lower pin then trigger the opening of fragment. Just do an if else statement – Mike Feb 02 '17 at 17:15
  • @Mike I will try to implement that but i have one last question. Won't the X and Y coordinates of the location pins change on different screens? – Neeraj Athalye Feb 02 '17 at 17:17
  • @Neeraj that got me thinking as well, anyways just log the x and y check it on two devices if its not equal then maybe you should just use the dimens approach. – Mike Feb 02 '17 at 17:20
  • 1
    @Mike Thank you. I will try out the above two approaches – Neeraj Athalye Feb 02 '17 at 17:21

1 Answers1

1

Give a try to constraint layout.They are great when it comes to resizing and placing components that should look same in all devices.You can find it here Constraint Layout Code Labs

Alternatively you can design the screen for various devices.For that you don't need the dimen.xml file, since they can be tricky. You can be make different layout files layout-large,layout-land,layout-xxxhdpi,layout-sw700dp. You can find it here Supporting multiple Screens in Android

Mike's solution in the comments for using x and y coordinates can also be applied here, but for that instead of taking the x and y coordinate you can place an transparent view over your location images.Those transparent views will shift a bit as per the device resolution but they will be largely on place to take your click event

Update

<FrameLayout 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.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="fitXY"
        android:src="@drawable/bg_image"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="1.0"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1" />

    <LinearLayout
        android:id="@+id/ll1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="6dp"
        android:layout_marginStart="6dp"

        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="@+id/ll2"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/ll2"
        app:layout_constraintTop_toTopOf="@+id/guideline2"
        app:layout_constraintVertical_bias="1.0">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_weight="38.89"
            android:text="Potheri"
            android:textColor="@android:color/black"
            android:textStyle="bold" />

        <ImageButton
            android:id="@+id/potheri_button"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#00000000"
            android:scaleType="centerInside"
            android:src="@drawable/location_pointer" />

    </LinearLayout>


    <android.support.constraint.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="20dp"
        tools:layout_editor_absoluteX="0dp"
        tools:layout_editor_absoluteY="101dp" />

    <!--<android.support.constraint.Guideline-->
    <!--android:layout_width="wrap_content"-->
    <!--android:layout_height="wrap_content"-->
    <!--android:id="@+id/guideline3"-->
    <!--app:layout_constraintGuide_begin="300dp"-->
    <!--android:orientation="horizontal" />-->

    <LinearLayout

        android:id="@+id/ll2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="32dp"
        android:layout_marginLeft="32dp"
        android:layout_marginRight="32dp"
        android:layout_marginStart="32dp"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="@+id/imageView"
        app:layout_constraintHorizontal_bias="0.38"
        app:layout_constraintLeft_toRightOf="@+id/ll1"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@+id/imageView"
        app:layout_constraintVertical_bias="0.36"
        tools:layout_constraintBottom_creator="1"
        tools:layout_constraintTop_creator="1">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:text="SRM"
            android:textColor="@android:color/black"
            android:textStyle="bold" />

        <ImageButton
            android:id="@+id/srm_button"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="#00000000"
            android:scaleType="centerInside"
            android:src="@drawable/location_pointer"
            android:textSize="20sp" />
    </LinearLayout>

   <TextView
       android:layout_width="0dp"
       android:layout_height="wrap_content"
       app:layout_constraintLeft_toLeftOf="parent"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintBottom_toBottomOf="parent"
       android:id="@+id/textView6"
       app:layout_constraintHorizontal_bias="0.0"
       tools:layout_constraintRight_creator="1"
       tools:layout_constraintLeft_creator="1"
       app:layout_constraintTop_toTopOf="@+id/guideline2"
       android:layout_marginTop="0dp"
       app:layout_constraintVertical_bias="0.68" />
    <LinearLayout
        android:id="@+id/ll3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:layout_constraintLeft_creator="1"
        tools:layout_constraintRight_creator="1"
        tools:layout_constraintTop_creator="1"
        app:layout_constraintTop_toBottomOf="@+id/textView6"
        android:layout_marginTop="0dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:text="Gudvancheri"
            android:textColor="@android:color/black"
            android:textStyle="bold" />

        <ImageButton
            android:id="@+id/guduvancheri_button"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="#00000000"
            android:scaleType="centerInside"
            android:src="@drawable/location_pointer"
            android:text="Gudvancheri" />
    </LinearLayout>



</android.support.constraint.ConstraintLayout>

The above is the best i could do given the scenarios, let me know if this works.

Alternatively you could divide the image into 3 parts to have a anchor for the ll3,ll2 and ll1.That way no mater how much the image stretches the layouts will always be pinned at a particular position.

Deb
  • 2,431
  • 3
  • 18
  • 28
  • i have implemented constraint layout in my code and it solves most of my problems but i am facing another issue now. For devices that have physical buttons for the back and recents panel(Example : OnePlus 2), the location of the pins is different than for other devices that have a virtual navigation bar(Example : nexus 5x). Any idea how i can solve that ? – Neeraj Athalye Feb 03 '17 at 21:28
  • You can find a useful link here http://stackoverflow.com/questions/14853039/how-to-tell-whether-an-android-device-has-hard-keys/14871974#14871974. it shows for to detect if the device has capacitive or on-screen buttons.Once you detected it you can may be load a different layout file which works best for capacitive button devices, but you have to keep all the @ids same in the new layout file as well, otherwise you will have to recode for different ids. OR you could dynamically change the constraint values to match that screen. – Deb Feb 04 '17 at 05:37
  • i implemented the layout that you game me. The upper row is almost perfect and moves every little with respect to the screen size but the lower button moves quite a lot when i change the device dimensions. Any idea why that must be happening? Also I wanted to re position the upper row also a bit but i am not able to do so. I am not able to move the components at all. Also i did not understand what exactly the guidelines are doing. I googled the guidelines but i did not understand what their function is. Could you kindly clarify that? – Neeraj Athalye Feb 05 '17 at 18:01
  • Updated the code to remove some of the unnecessary guidelines. To learn about guidelines follow this link https://developer.android.com/reference/android/support/constraint/Guideline.html – Deb Feb 05 '17 at 19:19
  • thank you so much for this solution! I just added a margin bottom attribute and now its working pretty consistently for all devices. – Neeraj Athalye Feb 05 '17 at 19:59