0

I've been trying for weeks to solve the problem of how to make my UI's text support all kinds of different device resolutions and densities without success. After reading the developers guide and multiple stack posts , i tried a lot of things. For starters, i created the layout directories that you can see in the image below (layout-sw320dp , layout-sw360dp and layout-sw400dp) :

layout dirs

Now if i test my app on a few different emulators, the UI's text seems fine but when my Alpha testers download the app on their phones, the UI's text gets misplaced. Here's the look i am trying to achieve across all devices :

desired look

Below i am adding 7 different devices which the alpha testers use:

1) S8+ (2960x1440)(529dpi)

2) Samsung galaxy j7 prime (1920x1080) (401dpi)

3) S8+ (1440x2960)(~529dpi)

4) Samsung A3 (960x540)(245dpi)

5) Motor z play Droid (1920x1080) (403 dpi)

6) Samsung Galaxy S7 (1440x2560) (577dpi)

7) Sony Xperia xa (720x1280)

After getting in touch with them, these are the images they sent me back(not everyone has answered yet):

2) 2nd

5)5th

6) 6th

7) 7th

I also have these lines of code that help me check whether the phone is an s8 or s8+ (since they need different layout styles due to their 18:9 ratio). Could this cause issues?

        // Get the user's phone's height and width
    DisplayMetrics dm = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(dm);

    // screen size in inches
    int height = dm.heightPixels;
    int width = dm.widthPixels;
    double x = Math.pow(width/dm.xdpi,2);
    double y = Math.pow(height/dm.ydpi,2);
    double screenInches = Math.sqrt(x+y);
    Log.d("SIZE_INCHES", screenInches + "\"");

    // If it's an S8 or S8+ choose the appropriate layout
    if (height > 1920 && height <= 2220) { // FHD+ (2220x1080)
        if(screenInches <= 6.0) {
            setContentView(R.layout.cardview_s8); //s8
        } else {
            setContentView(R.layout.cardview_s8_plus); // s8+
        }
    } else if (height > 2220 && height <= 2960) { // S8 WQHD+ (2960x1440)
        if(screenInches <= 6.0) {
            setContentView(R.layout.cardview_s8_wqhd_res);
        } else {
            setContentView(R.layout.cardview_s8_plus_wqhd); // s8+
        }
    } else { // otherwise choose the appropriate layout for the user's phone based on it's swdp qualifier
        setContentView(R.layout.cardview);
    }

Here's my layout(design view) for reference:

layout

And here's the xml code:

<?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:background="@drawable/card_view_bg"
tools:layout_editor_absoluteY="25dp">

<ImageView
    android:id="@+id/cardArtImageView"
    android:layout_width="400dp"
    android:layout_height="0dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:layout_weight="1"
    android:adjustViewBounds="true"
    android:scaleType="fitCenter"
    app:layout_constraintBottom_toTopOf="@+id/cardDetailsImageView"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<ImageView
    android:id="@+id/cardDetailsImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    android:cropToPadding="false"
    android:scaleType="fitXY"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:srcCompat="@drawable/card_details_box" />

<TextView
    android:id="@+id/leaderSkillDesc"
    android:layout_width="300dp"
    android:layout_height="19dp"
    android:layout_marginBottom="8dp"
    android:layout_marginStart="40dp"
    android:layout_marginTop="8dp"
    android:ellipsize="marquee"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:fontFamily="monospace"
    android:marqueeRepeatLimit="marquee_forever"
    android:scrollHorizontally="true"
    android:singleLine="true"
    android:textAlignment="viewStart"
    android:textColor="@color/white"
    android:textSize="13sp"
    android:textStyle="italic"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.496"
    app:layout_constraintStart_toStartOf="@+id/cardDetailsImageView"
    app:layout_constraintTop_toTopOf="@+id/guideline8"
    app:layout_constraintVertical_bias="0.626" />

<TextView
    android:id="@+id/superAttackDesc"
    android:layout_width="314dp"
    android:layout_height="21dp"
    android:layout_marginBottom="8dp"
    android:layout_marginStart="40dp"
    android:layout_marginTop="8dp"
    android:ellipsize="marquee"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:fontFamily="monospace"
    android:marqueeRepeatLimit="marquee_forever"
    android:scrollHorizontally="true"
    android:singleLine="true"
    android:textAlignment="viewStart"
    android:textColor="@android:color/white"
    android:textSize="13sp"
    android:textStyle="italic"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="@+id/guideline9" />

<TextView
    android:id="@+id/superAttackTitle"
    android:layout_width="250dp"
    android:layout_height="15dp"
    android:layout_marginBottom="8dp"
    android:layout_marginEnd="8dp"
    android:layout_marginStart="8dp"
    android:fontFamily="monospace"
    android:textAlignment="viewStart"
    android:textColor="@android:color/holo_blue_light"
    android:textSize="14sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toTopOf="@+id/superAttackDesc"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent" />

<android.support.constraint.Guideline
    android:id="@+id/guideline8"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_begin="443dp" />

<android.support.constraint.Guideline
    android:id="@+id/guideline9"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_begin="596dp" />

</android.support.constraint.ConstraintLayout>

What am i doing wrong here? I've never been more confused in my life in android development... Is there a more explicit way for this job? Do i need more layout dirs or something? Are those 3 layout dirs correct? Please if you know anything that could help me, post it down below.

PS: I'm using a Constraint Layout for this part of the UI, could the constraints be causing the issue?

Stelios Papamichail
  • 955
  • 2
  • 19
  • 57
  • 2
    The entire point of layout dirs is not to do what you do with multiple calls to setContentView. SO you're definitely confused somewhere. TO even approach any help you need to give a lot of details about exactly how you're doing the drawing- how many views, what are bitmaps and what's open gl, which/how are certain bitmaps being strectched to fit the screen exactly and which aren't, etc. If you're looking for pixel perfect layout across all devices on a highly graphic design like this, you need to think it out in detail. – Gabe Sechan Dec 20 '17 at 19:47
  • @GabeSechan do bitmaps matter in my case since the problem is with the text? And yeah i'm pretty sure i'm confused in general with this entire thing. – Stelios Papamichail Dec 20 '17 at 20:57
  • You're writing the text on top of bitmaps. If you're trying to get away with just 1 giant image you're writing text on- yeah, you're gonna have a bad time. – Gabe Sechan Dec 20 '17 at 21:10
  • oh right, i just realised that. Thanks for pointing it out. What can be done about it? Is the image stretching causing the text's strange behavior ? – Stelios Papamichail Dec 20 '17 at 21:14
  • A good part of it. I'd be rendering each part of your UI as a separate view- 1 for the background, 1 for the character image, 3 (in a linear layout) for the HP/ATK/DEF, etc. Then the placing of your views relative to one another dictates the size and location of your text. Doing it that way, you only need one layout for all sizes, with possibly some higher and lower res images for different dpi. – Gabe Sechan Dec 20 '17 at 21:17
  • Sorry if i'm asking stupid stuff here but what do you mean as seperate views? Isn't each UI element in my layout a view?(2 image views and 3 textViews)? Do you suggest placing them inside other layouts(linear,relative etc.) and re-positioning them? – Stelios Papamichail Dec 20 '17 at 21:23
  • I have no idea how many views you have in your layout since you didn't post it. But basically each tag in your layout is a view. If you're doing it with just 5- that's your problem. I see about 2 dozen doing it the right way. My guess is your entire bottom half is one image? That's an unusable design for multiple screens. – Gabe Sechan Dec 20 '17 at 21:24
  • i'm adding the layout image and xml code for reference. Seriously a dozen huh? Wow! And yes the entire bottom half is actually one image. How would that help the layout though in rendering the images differently? Is there a link you can point me to? *Thanks for helping me btw – Stelios Papamichail Dec 20 '17 at 21:27
  • Because you can't just stretch out images like that and expect it to work. And its more like 2 dozen. Each visual element (piece of text, image, progress bar, etc) should be its own view. And the overall layout. Expecting to put an image on screen and layout text on top of it and have it match up only works if you have a single size screen to work on. Otherwise you're going to have issues, its not the right way to design things. – Gabe Sechan Dec 20 '17 at 21:31
  • 1
    Imagine instead you had a RelativeLayout for the bototm, whos'e background was just the funky rectangle thing. Then you could say where, relative to that view, to put the different things inside of it. Since you're doing all of it via the layout, you can tell it exactly where to put the text views- for example say to layout the text and align its top to the top of the view that says "Leader skill". And put the Stuff that says "Special Attack" below that. Etc. – Gabe Sechan Dec 20 '17 at 21:34
  • Would the text though need to be in something like a separate LinearLayout(Vertical) so that they have their "own view"? – Stelios Papamichail Dec 20 '17 at 21:43
  • Probably a TextView, not a LinearLayout – Gabe Sechan Dec 20 '17 at 21:44
  • so leave them as is, ok. I'll give it a try, i think i understand what you're saying. Thank you for your time and effort. Let's hope i won't need to come back here again for this problem – Stelios Papamichail Dec 20 '17 at 21:46

2 Answers2

0

The issue has been solved by @Gabe Sechan (for anyone checking back), check the comments below the post!

Stelios Papamichail
  • 955
  • 2
  • 19
  • 57
-1

It looks like you have a background image and you are trying to place text in the right position over that background image. Can you split the background image up and use the pieces as a Button background image? Better yet use a recycler view? I realize now the pieces might not align properly for the whole image. Is the artist available? Good luck to you on this, I know how difficult it is to get things to work on every device. You do seem to have a good grasp of the concept

Pomagranite
  • 696
  • 5
  • 11
  • How would a RecyclerView help him? There's no repeated elements to be recycled. – Gabe Sechan Dec 20 '17 at 19:51
  • https://stackoverflow.com/questions/26245139/how-to-create-recyclerview-with-multiple-view-type – Pomagranite Dec 20 '17 at 20:17
  • Yes, you can create on with multiple view types- but if there's no repetition, there's nothing to be gained by using a recycler view. There is nothing remotely calling for a recycler view in his design. If you're suggesting to use RecyclerView for its layout ability, that's the worst use of it I've ever heard suggested. – Gabe Sechan Dec 20 '17 at 20:20
  • @Pomagranite hi mate, like i mentioned in the title and in the op, i don't have any issues with the images but with the text which is not aligning correctly ;) – Stelios Papamichail Dec 20 '17 at 21:08
  • @Stelios Papamichael have you experimented with measurements https://developer.android.com/guide/practices/screens_support.html "Using new size qualifiers" – Pomagranite Dec 20 '17 at 21:36