I'm doing an Android App for Android tablets that has a full image background but I can't use a 9-patch, so I need the background to be as close as possible as the window size.
I've tested using the drawable-ldpi
, drawable-mdpi
, etc... folders but as I want the images to fit the window, it doesn't work that well.
Now I'm trying with the drawable-wxxxdp
, folders to have images with sizes that are close to the real window size.
So I have this folder structure (each folder with a different image, i.e: images of same size are different on different folders):
drawable-w800dp-mdpi // 800x600px image
drawable-w800dp-hdpi // 800x600px image
drawable-w1024dp-mdpi // 1024x600px image
drawable-w1024dp-hdpi // 1024x600px image
drawable-w1280dp-mdpi // 1280x800 image
drawable-w1280dp-hdpi // 1280x800 image
drawable-w1280dp-xhdpi // 1280x800 image
The problem is that when I test the App on different tablets it doesn't always take the image from the expected folder.
For instance: in a 1280x800px and 160 dpis tablet, that reports (using DisplayMetrics
) a window size of 1280x752, it uses the 1280x800px image from the drawable-w1280dp-mdpi
folder and cuts a bit of the image from the top and the bottom. But on a 1280x800px and 213dpis tablet
that reports a window size of 1280x736 it takes the image from the drawable-w800dp-hdpi
... I would expect to take it from other folder like one of the drawable-w1024dp folders... but not from that one...
On the other hand if I try on the emulator with a configuration like 1024x600px and 160dpis that reports a window size of 1024x552 it gets the image from the drawable-w1024dp-hdpi
folder but it scales it down and centers it on the screen so I end with very big border all around the image.
The testing layout I'm using is:
<RelativeLayout 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" >
<ImageView
android:id="@+id/appBackground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="@drawable/background_image"
tools:ignore="ContentDescription" />
</RelativeLayout>
and on my Manifest file I have:
<uses-sdk
android:minSdkVersion="13"
android:targetSdkVersion="15" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:resizeable="true"/>
Update: My activity code:
public class ScreenTest extends Activity {
private int width;
private int height;
private int dpis;
private String sdpis;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Ask for a full screen window
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_screen_test);
}
/* (non-Javadoc)
* @see android.app.Activity#onCreateView(java.lang.String, android.content.Context, android.util.AttributeSet)
*/
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
return super.onCreateView(name, context, attrs);
}
/* (non-Javadoc)
* @see android.app.Activity#onStart()
*/
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
// Get the info about the screen
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();// size.x;
height = display.getHeight();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
dpis = outMetrics.densityDpi;
sdpis = "";
switch (dpis) {
case DisplayMetrics.DENSITY_DEFAULT:
sdpis = "160";
break;
case DisplayMetrics.DENSITY_HIGH:
sdpis = "240";
break;
case DisplayMetrics.DENSITY_LOW:
sdpis = "120";
break;
case DisplayMetrics.DENSITY_XHIGH:
sdpis = "320";
break;
default:
sdpis +=dpis;
break;
}
Log.d("DPIs", "dpis: " + dpis + " sdpis: " + sdpis + " width: " + width + " height: " + height);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_screen_test, menu);
return true;
}
}
So I don't know how to predict from which folder is the App going to take the image? and what it will do with it? (scale, crop...)
I've checked all the questions on the android-resoruces tag, I've read several times the official documentation:
and some related questions:
Update: fixed typos in the folder names.
Hdpi is a 1.5:1, and can be thought of as a HD (high-definition) display. And xhdpi is 2:1, much like Apple retina displays. . The normal mdpi is based on a 160 dpi screen, which again is the same as a single pixel unit in your graphics software.
Choose the most appropriate decode method based on your image data source. These methods attempt to allocate memory for the constructed bitmap and therefore can easily result in an OutOfMemory exception. Each type of decode method has additional signatures that let you specify decoding options via the BitmapFactory.
Why is it problematic to define sizes using pixels on Android? Although screen pixel density varies, this does not impact the use of pixels to define sizes. Large devices always have more pixels, so your UI elements will be e=affected if you define them with pixels.
If you want to target specific device. or all devices that are in-between two resolutions then you have to find width of device first. like this
Display display ;
int width =0;
display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
after that you can make if statements with width conditions and make different layouts for different screens size. this one is not recommended method but work great in some case
if(width>=750)
{
setContentView(R.layout.screen_blue_heigh);
}
else if(width>=500&&width<750)
{
setContentView(R.layout.screen_blue_heigh);
}
else if(width<500&&width>=330)
{
setContentView(R.layout.screen_blue_medium);
}
else if(width<320)
{
setContentView(R.layout.screen_blue_low);
}
Hope this will help you.
you are right it will pick resource from w800dp
, coz you are running in portrait mode.
The system's corresponding value for the width changes when the screen's orientation switches between landscape and portrait to reflect the current actual width that's available for your UI.
use res/drawable-sw600dp
the device's smallestWidth does not change when the screen's orientation changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With