android layout smallest width (sw800dp) and different densities - android

How can I put different resources for different dpi on ICS with the same sw800dp smallest width?
Details: There are two tablets with ICS 4.0.4. First one has 1280x800 resolution and mdpi (160) density. Second one has 1920x1200 resolution and hdpi (240) density. So in terms of smallest width they both have the same sw800dp qualifier but different mdpi/hdpi density qualifiers.
I need to have different layouts and images for these two resolutions.
So I created two directories:
layout-sw800dp-mdpi
layout-sw800dp-hdpi
I thought that each device will choose its own directory according to the smallest width AND density.
BUT both of them take resources from the same sw800dp-hdpi folder!
I'm very confused and do not know how to separate resources for that two different resolutions.
Any help is really appreciated.
Thanks in advance.

You should use the same layout, located in /layout/sw800dp, and create /drawable-mdpi , /drawable-hdpi to put your custom drawables, the system will apply the correct ones to each device, using the same layout. Those devices should have similar size and aspect...

Use this to get the density:
float density = getBaseContext().getResources().getDisplayMetrics().density;
Screen height:
int h = 0;
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
h = (int) display.getHeight();
Screen width:
int w = 0;
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
w = (int) display.getWidth()
After that just select the correct resources.

Related

Android layout Support multiple Screens

I know this question has been answered many times but those answers are not helping me out. My app is looking perfect on 5inch screen but on 6 inch and more the alignment is different. I have added tag in manifest also...and also designed layout,layout-large,layout-normal also.
I want to know what is the best way to make the layout supports all screen without making 3 or 4 layouts for one screen.
To support multiple resolutions, you may use multiple layout files, but using a single layout file makes file maintenance and management easier. When you need to modify part of the layout for different resolutions, it is good to use dimens.xml, which makes it easy to modify.
This link may help you:
http://developer.samsung.com/technical-doc/view.do;jsessionid=4D620DFCC329BEC0DB60E73C6B185743?v=T000000126
sorry for answering instead of commenting but that is because of my low reputation, you can find this article helpful for you for the developers of google
https://developer.android.com/guide/practices/screens_support.html, Also this video
https://www.youtube.com/watch?v=GTd7QVv7lzg
There are different ways to approach your problem.
1. You can create different XML s for a same layout based on the screen sizes like normal, 7 inch and ,for large screens (i don't recommend this though )
A set of six generalized densities:
ldpi (low) ~120dpi
enter code here
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi
xxxhdpi (extra-extra-extra-high) ~640dpi
read here(how to create multiple XMLS) --> https://developer.android.com/guide/practices/screens_support.html
2.Give sizes based on a ratio
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenHeight = size.y;
screenWidth = size.x;
now you have values for the screenHeight and screenWidth of that particular devise
now position layouts
eg: how to position a view as linear
topLinearLayout = (LinearLayout) inflateView.findViewById(R.id.top_len_one);
topLinearLayout.setGravity(LinearLayout.HORIZONTAL);
topLinearLayout.getLayoutParams().width = width;
topLinearLayout.getLayoutParams().height = 495 * height / 1920;
eg: how to position a view as relative
RelativeLayout.LayoutParams relativeLayoutForPassword = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
relativeLayoutForPassword.setMargins(screenWidth * 240 / 1080, screenHeight * 960 / 1920, 20, 0);
editTextPassword.setLayoutParams(relativeLayoutForPassword);
// 1080 is my default wire frame's design width , 1920 is height (in pix)
so its like ,
i have an image which is 1920 in height and 1820 in width
create a layout which has 210 height in my default wire frame's design height and set resize it to my devise screen size --> 210/1920 * your devise height
this keeps the perfect ratio for any screen

How to prepare android screen independent graphic - specific solution

Is it possible to use common hdpi folder for all screen densities? I have quite a lot images. If I make specific copies to folders drawable-hdpi, drawable-ldpi, drawable-xhdpi, ... but it takes huge data (backgrounds, bitmaps).
Is it possible to set only one drawable folder for all devices and then rescale according to a specific device programmatically?
I think about this code to get display size of the scree:
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
Then I will get display density of the device, something like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
density = metrics.density; // 1 - 1,5 - 2 .....
The I will recalculate size of imageview with density:
ImageView logo = (ImageView)findViewById(R.id.logo);
LinearLayout.LayoutParams logo1 = (LinearLayout.LayoutParams) logo.getLayoutParams();
logo1.width = (int)(logo.getWidth()*density);
logo1.height = (int)(logo.getHeight()*density);
logo1.leftMargin=(int)(logo1.leftMargin*density); // for margin
logo1.topMargin=(int)(logo1.topMargin*density); // for margin
logo1.rightMargin=(int)(logo1.rightMargin*density); // for margin
logo1.bottomMargin=(int)(logo1.bottomMargin*density); // for margin
My main problem is I need to have all proportions of graphic same on all devices. It means I must recalculate imageViews accroding to the screen size.
Is this a right way to get density independent screen? How does android work on other devices if only hdpi folder contains files. Does it take files from this folder? Can I set one common drawable folder to all densities?
I would strongly (strongly) advise against doing this. However, if you want the system to rescale your image assets, design them for mdpi (the baseline density) and put them in drawable/.
That said, you need at least mdpi and hdpi to get reasonable scaling (since hdpi is 1.5x mdpi, scaling algorithms produce worse results than for the other conversions from mdpi).
Make sure you've read and understood Providing Resources and Supporting Multiple Screens before you start dealing with resources.
P.S. The layout solution is wrong for a few reasons (e.g., setting margins instead of size) but it's also the completely wrong thing to do. Don't do it!

Can I change device DPI programmatically?

I was wondering if I can change device which decides which layout it should choose or which graphic it should choose/scale. This change should only affect my application of course. Can I set somehow device DPI?
The reason why I'm doing that is this phone: http://www.gsmarena.com/samsung_p1000_galaxy_tab-3370.php it has very bad DPI od 240DPI while it's only 170PPI and should be recognized as 160DPI device.
I have quite big graphic for layout-large which looks great on mdpi, but on hdpi they doesn't fit, they are just to big.
Maybe you have another solution than changing device DPI?
Yes it is possible.
The following will set the dpi to 240. Although you have to refresh the activity somehow e.g. restart application.
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
metrics.density = 1.5f;
metrics.densityDpi = 240;
metrics.heightPixels = 1104;
metrics.widthPixels = 1920;
metrics.scaledDensity = 1.5f;
metrics.xdpi = 254.0f;
metrics.ydpi = 254.0f;
getResources().getDisplayMetrics().setTo(metrics);
you should create your application
to support with multiple screens.take a look at documentation
and hope these links helps you
Designing for Multiple Screens
Working with Multiple Android Screens
Samsung Galaxy Tab GT-P1000 take layout from layout-xhdpi if this not there then it will look for large.
Try to support multiples screen resolution for your app based on that documentation
you have to Design alternative layouts and drawables for your app

layout management in android

I have created an app for all screen resolutions. So for that, according to the documentation I have created a list of resource directories in an application that provides different layout designs for different screen sizes and different bitmap drawables for medium, high, and extra high density screens.
For example:
res/layout-normal/my_layout.xml // layout for normal screen size ("default")
res/layout-small/my_layout.xml // layout for small screen size
res/layout-large/my_layout.xml // layout for large screen size
res/layout-xlarge/my_layout.xml // layout for extra large screen
Now while running my app in different device what I notice that some of the devices with different screen resolution take the layout from the same resource directories i.e. layout-normal, and example of such devices are:
HVGA (320 x 480)
WQVGA 400 (240 x 400)
WVGA (480 x 800)
WXGA (720 x 1280)
Due to the use of layout from the same resource directories i.e. layout-normal it very difficult for me to manage the space between the UI for all devices as they take the same layout. Because if I manage the layout for HVGA then it doesn't look good in other, because of resolution.
So is there any way to solve this problem? Please help me to solve this out.
Dont prepare xml for each layouts. just make images for all (ldp, mdpi , hdpi) with same name and put in this different folder as per size.
ldpi : 240X320
mdpi : 320X480
hdpi : 480X800
And give permission in android Android Manifest file.
<supports-screens android:normalScreens="true"
android:anyDensity="true" android:largeScreens="true"
android:smallScreens="true" />
i am apply this way to make universal app in android.it will work fine, try like this way..
#hasMukh has pointed the right direction, but if you want the layouts for those 4 devices to be more precise. I suggest you to use the "layout-density-resolution" format for layout folder naming. As an example,
for HVGA(320x480) layout folder should be "layout-hdpi-480x320"
for WQVGA(240x400) layout folder should be "layout-ldpi-400x240"
for WVGA(480x800) layout folder should be "layout-mdpi-800x480"
for WXGA(720x1280) layout folder should be "layout-mdpi-1280x720"
This method is only good if you are planning to target specific few devices..and you can keep only one drawabale folder and use dp values for layouts.
i have the same problem, i used another approach.
get device height/width :
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); // the results will be higher than using the activity context object or the getWindowManager() shortcut
wm.getDefaultDisplay().getMetrics(displayMetrics);
screenWidth = displayMetrics.widthPixels;
screenHeight = displayMetrics.heightPixels;
and check the device height/width according to that i used layout like
if(screenWidth == 320 || screenHeight== 480){
setContentView(R.layout.test_320_480);
}else if(screenWidth == 240 || screenHeight == 320){
setContentView(R.layout.test_240_320);
}else if(screenWidth == 480 || screenHeight == 800 || screenHeight == 854){
setContentView(R.layout.test_480_800);
}
use the same id for each controls in the layout for same screen.i hv put all layout in layout folder and it works for me.

Separate graphics for different resolutions, android

I need drawable resources for different resolutions, such as 320x480, 800x480, 854x480, 800x600
1024x600, 1024x768, 1024x800. It is a game and the scaling of bitmaps is inacceptable, coz they are very sensitive to it. dpi dependent folders and combination with screen sizes(which are deprecated but no other way to set drawable for large screens with same resolution and differend dpi) are not enaugh. How to distinguish graphics for 1024x600 and 1024x768 for example?
It is so sad to stop use mechanism of auto picking resources and switching to manual loading from assets.
any ideas?
I'm usually using 4 resource folders for drawables:
drawable-mdpi for 320x480
drawable-hdpi for 480x800 and 480x854
drawable-large-hdpi for 600x1024, 768x1024 and so on
drawable-xlarge-mdpi for 800x1280
These are just enough in my mind. Also, you don't need to worry about different drawable resources for, in example, devices with 800x480 and 854x480 screen sizes: you can specify an offset on the edges of your screen equal to 27 pixels and center your game on the screen. Hope this helps.
If you want a pixel perfect fit you could always load the background at runtime via a simple method:
private void setBackgroundImage() {
DisplayMetrics dm = getResources().getDisplayMetrics();
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
// TODO: Conditional Structure to apply the right drawable
// ressource to be applied in the background
}
After you've acquired the resolution of the display you can apply the appropriate background via the setBackgroundDrawable method.

Categories

Resources