2

I don't have an Nexus 5x device, but I'm using Emulator.

Edit: Confirmed from a Nexus 5x user. Its not an Emulator bug.

Problem:

On Nexus 5x app loads incorrect size drawables. While on Nexus 5 is fine.

Right - Nexus 5 , Left - Nexus 5X

I have an image original size 1440x2560. Resized it to drawable-xxhdpi - 1080x1920

Log returns me something interesting too:

Nexus 5:
Display Width= 1080 Display Height= 1776
Background Width= 1080 Background Height= 1920

Nexus 5x:
Display Width= 1080 Display Height= 1794
Background Width= 945 Background Height= 1680

My code.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.myapp.backgroundisfdupyo">    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"

        android:theme="@android:style/Theme.NoTitleBar.Fullscreen">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.java

public class MainActivity extends Activity {

private static final String TAG = "Main";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    logScreenSize();
}

private void logScreenSize() {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

    int displayW = displayMetrics.widthPixels;
    int displayH = displayMetrics.heightPixels;

    Log.e(TAG,"displayW= " + displayW + " displayH= "+ displayH);

    Drawable bckg = getResources().getDrawable(R.drawable.background);
    Log.e(TAG,"Background Width= " + bckg.getMinimumWidth() + " Background Height= "+ bckg.getMinimumHeight());
}

@Override
protected void onStart() {
    super.onStart();
    toggleHideyBar();
}

public void toggleHideyBar() {
    int newUiOptions = 0;

    // Navigation bar hiding:  Backwards compatible to ICS.
    if (Build.VERSION.SDK_INT >= 14) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
    }

    // Status bar hiding: Backwards compatible to Jellybean
    if (Build.VERSION.SDK_INT >= 16) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
    }

    if (Build.VERSION.SDK_INT >= 18) {
        newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
    }

    getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
    //END_INCLUDE (set_ui_flags)
}

activity_main.xml

...
<FrameLayout
    android:id="@+id/backgroundFrame"
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent">

<ImageView
    android:id="@+id/backgroundImage"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    android:src="@drawable/background" />

</FrameLayout>

Edit:

Resource Tree as requested.

enter image description here

\drawable-xxxhdpi\background.jpg  - 1440 x 2560    
\drawable-xxhdpi\background.jpg   - 1080 x 1920    
\drawable-xhdpi\background.jpg    -  720 x 1280    
\drawable-hdpi\background.jpg     -  540 x 960    
\drawable-mdpi\background.jpg     -  360 x 640    
\drawable-ldpi\background.jpg     -  270 x 480

Edit:

https://android-developers.googleblog.com/...

It has a quantized density of 560 dpi, which falls in between the xxhdpi and xxxhdpi primary density buckets. For the Nexus 6, the platform will scale down xxxhdpi assets, but if those aren’t available, then it will scale up xxhdpi assets.

How do I turn it off ? I want my project to ONLY take images from my premade images, I don't want it to scale up/down something.

keyur patel
  • 99
  • 1
  • 7
paakjis
  • 369
  • 4
  • 16
  • try scaleType `fitCenter` or show your res folders tree – egoldx May 09 '17 at 10:19
  • Looks like your ImageView height not match_parent. Try to set it with match_parent. And I see a constraints in your FrameLayout that's means that you're using FrameLayout in ConstraintLayout, why? Try to use one of them – Skullper May 09 '17 at 11:00
  • @PavliukR I took it out of FrameLayout, it did fill the screen like on Nexus 5x, but the log still says that loaded bacground image is Width= 945 Height= 1680 , where it should load like Nexus 5 Width= 1080 Height= 1920 . I think it just stretched the image. – paakjis May 09 '17 at 11:12
  • @user1779222 nothing changed. I posted resource tree and their size. As you see, none of the images are 945 x 1680 , where does Nexus 5x pull it out from ? – paakjis May 09 '17 at 12:34
  • It's obvious that your emulator resolution config set as xxhdpi, not xxxhdpi. You can see that 'Display Width= 1080' part from logs. AVD creates xxhdpi Nexus 5X as default. Check my answer. I never faced with nexus 5X bug in real devices. – Oğuzhan Döngül May 09 '17 at 14:23
  • set your image through dimen instead of drawable folder – scienticious May 10 '17 at 07:19
  • @scienticious Sorry, can you explain more what did you mean ? – paakjis May 10 '17 at 09:16

2 Answers2

1

When loading drawables, Android scales the images to match the screen density.

Screen densities don't always match the predefined densities like hdpi (1.5x), xhdpi (2x), etc. And usually you don't provide images for all predefined densities: in your example you didn't provide tvdpi (1.33) for example. That's why in these cases the system will resize one of the provided images to match the screen density as best as possible.

The Nexus 5x and Google Pixel phones have a density factor of 2.6. On these phones the system will try to scale down the xxhdpi (3x) images, or scale up the xhdpi (2x) images if not available.

If you want to disable scaling completely, you can put images in the drawable-nodpi folder and they will always show the same number of pixels on every screen. However, that's probably not what you want because the image will appear too small on higher-density screens and too big on lower-density screens.

What bothers you seems to be the space around the image. It's normal that an image takes up a smaller portion of the screen when the total screen space is bigger. A Nexus 5x offers more screen space than a Nexus 5. A tablet offers more screen space than a phone. And there is an infinite number of possible screen sizes so you can't create an image that will perfectly match each of them.

However, you can center an image in the middle of the screen on top of some background, or you can scale the image using the CENTER_CROP mode of ImageView to make it fill the whole screen by cutting some edges.

BladeCoder
  • 12,779
  • 3
  • 59
  • 51
  • Yes. That's the problem. It still feels so wrong that the screen is 1080x1920 , but it takes xhdpi (720x1280) image and scales it up automatically to 945 x 1680, and then I need to scale it up more with CENTER_CROP so it fits the screen. – paakjis May 11 '17 at 10:38
  • If you put the image in drawable-nodpi folder and use CENTER_CROP, it will be loaded in its original size and scaled up or down once to fit the screen. – BladeCoder May 11 '17 at 10:47
  • This would only work for a background. But if there are ImageButtons. It still just scales down the image. And then I need to scale it up again. I think there should be a way to tell it to stop scaling it down, just use the one of the six images packs I have prepared ( no in-between ) – paakjis May 11 '17 at 11:25
  • CENTER_CROP only works for the src image in an ImageView or an ImageButton, not backgrounds. Unfortunately you can only choose between accurate scaling or no scaling at all. For small icons you should consider using Vector Drawables providing a sharp display at every density. – BladeCoder May 11 '17 at 11:45
0

UPDATE: Reason of the problem is probably about screen size and density both, not only about density.

Try This Solution:

create a new drawable folder like below

drawable-large-xxxhdpi

Your device has large screen. This can be fix your problem.

Check this question, you can see your device size and density.


You need to change Emulator Resolution.

First, close your emulator and open AVD Manager from Android Studio Find your Nexus 5X device and check its resolution. If it is not correct, click edit button as shown below.

enter image description here

Second, the window opened, click Change button.

enter image description here

Third, click New Hardware Profile

enter image description here

At last, change resolution as you want to be and click Finish button.

enter image description here

Community
  • 1
  • 1
Oğuzhan Döngül
  • 7,856
  • 4
  • 38
  • 52
  • Thanks for your answer. It is set correct. My friend has an Nexus 5x , I sent him this app. He sent back a screenshot, and the problem is still there. The issue here is something to do with resources. Why does it load smaller than 1080 x 1920 image. – paakjis May 10 '17 at 06:13
  • @paakjis Updated my answer, may be this update solve your problem, or make you closer to solution. – Oğuzhan Döngül May 10 '17 at 07:09
  • Nothing changed. I tried the link you posted, and it says "Normal screen" on my app. So I guess its normal and it will not load large on it. – paakjis May 10 '17 at 09:15
  • @paakjis it's interesting, when I create an emulator for 5X and set normal features, it seems long-large-xxxhdpi. – Oğuzhan Döngül May 10 '17 at 09:29
  • Yes, it does say it on mine too. But I guess it doesn't work like that. – paakjis May 10 '17 at 09:44
  • On Density it says 420dpi, but on Nexus 5 it says xxhdpi. Does it mean its neater normal or large ? – paakjis May 10 '17 at 09:56