1

I can't get the elements to position correctly on my layout in Android Studio. I have an ImageView with a png background containing the number 2. I have two Views each containing a small circle. I want the circles to always align at each tip of the number two. I can align them correctly on one device but the alignment changes on a different device. Is it possible to make these always align correctly in every device?

Here is what I want it to look like: https://i.stack.imgur.com/v7nsg.png

Here is my code to calculate the one of the dots position:

    circle2 = findViewById(R.id.circle2);

    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    int heightPixels = metrics.heightPixels;
    int widthPixels = metrics.widthPixels;

    //dimensions of background image: 547x839

    dot2H = (heightPixels / 547) * 70;
    dot2W = (widthPixels / 829) * 70;
    dot2Hposition = (heightPixels / 829) * 500;
    dot2Wposition = (widthPixels / 547) * 300;
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) circle2.getLayoutParams();
    params.height = dot2H;
    params.width = dot2H;
    params.leftMargin = dot2Wposition;
    params.topMargin = dot2Hposition;
    circle2.setLayoutParams(params);

Here is the layout code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@drawable/bg"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="net.beauvine.animationtest.MainActivity"
tools:showIn="@layout/activity_main">
<ImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerInside"

    android:src="@drawable/two"
    android:id="@+id/imageView"
    android:padding="10dp"
    android:layout_alignParentEnd="false"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true" />

<RelativeLayout
    android:id="@+id/dotLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:gravity="center"
    >

    <View android:layout_width="70dp"
        android:layout_height="70dp"
        android:id="@+id/circle2"
        android:background="@drawable/circle"
        android:clickable="true"
        android:alpha=".8"
        />
    <View android:layout_width="70dp"
        android:layout_height="70dp"
        android:id="@+id/circle"
        android:background="@drawable/circle"
        android:clickable="true"
        android:alpha=".8"
        />

</RelativeLayout>

1 Answers1

1

Android is used on a very large number of devices with very different screen sizes and density. Because of this it's hard to do what you want via xml layout. But you can use layout with fixed relations of views so it will look similar to what you want but this isn't good approach.

This example can give you a key. This layout shows 4 views in exact places of screen always.

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="2">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">

            <View
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:background="@android:color/white" />
        </FrameLayout>

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">

            <View
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:background="@android:color/white" />
        </FrameLayout>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal"
        android:weightSum="2">

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">

            <View
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:background="@android:color/white" />
        </FrameLayout>

        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1">

            <View
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:background="@android:color/white" />
        </FrameLayout>
    </LinearLayout>

</LinearLayout>

Something like this one:

enter image description here

Better if you will draw both background (with number 2) and circles in custom view. So you'll know exact sizes and coords of all object and can place them correctly.

Just example of drawing in custom view:

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }

    public class MyView extends View {
        public MyView(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }

        @Override
        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);

            int x = getWidth();
            int y = getHeight();
            int radius;
            radius = 100;
            Paint paint = new Paint();
            paint.setStyle(Paint.Style.FILL);
            paint.setColor(Color.BLACK);
            canvas.drawPaint(paint);

            paint.setColor(Color.WHITE);
            canvas.drawCircle(x / 2, y / 2, radius, paint);

            paint.setColor(Color.WHITE);
            canvas.drawCircle(x / 3, y / 3, radius, paint);
        }
    }
}

Hope this helps.

comrade
  • 4,590
  • 5
  • 33
  • 48
  • I have been trying out your custom view suggestion and it seem to be getting me closer to my goal. However, one thing that I did not clarify before is that the dots are buttons that animate when you touch them. How do I incorporate that? In your example you drew circles on a canvas. Unfortunately, those cannot be buttons. – Beau Carnes Jun 23 '16 at 18:17
  • You need to create specific object which will draw itself and handle touch action (like View). Do you programming something like a game? In this case you can try to use one of free game engines. They all support custom drawing, animation of objects, necessary interaction etc. – comrade Jun 23 '16 at 19:01
  • Thanks for the help! I ended up making another custom view for each dot and I made those into buttons. Your solution definitely got me on the right path. – Beau Carnes Jun 23 '16 at 20:19