I have a view in my android app that I would like to toggle between visible/gone on smaller screens, and visible/invisible in larger sizes. The initial set up (gone for small, invisible for large screens) is done by having two separate XML layout files under layout and layout-sw600dp-land, but then when I need to dynamically swap the visibility setting, how can I determine from within Java code which one to pick based on screen size?
Edit: more specifically, I want to detect in my code the same condition that causes Android to use layouts from layout-sw600dp-land. I was thinking even recording the value somewhere in the values-sw600dp-land directory, but not sure which file to put it into and how to access it.
You can get the size in pixels of the screen using the following.
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
However, your question was ambiguous as to whether size of screen meant pixels or inches. You may need to take advantage of the dm.densityDpi value, to convert the values from pixels to inches, for a more useful calculation of the "size" of the screen.
ANSER FOR EDITS:
There are two potential solutions. One is referenced in this thread, very simple and you alluded to it above.
How to programatically determine which XML layout my Android apps is using?
The second isn't a solution, but rather an explanation. The layout-sw600dp-land file replaces an old naming convention pre 3.2 that went like this layout-xlarge-land. This essentially manes "xlarge" screen in "landscape" mode. So you can detect this programmatically by finding xlarge screen sizes, in which the width > height. Below is a good reference to compare the old convention vs the new "sw600dp" = smallest width is 600 dp convention.
http://developer.android.com/training/multiscreen/screensizes.html
Related
I don't know if such devices really exist but, considering that they could, consider the following two devices:
I was trying to adjust size of widgets giving them a certain percentage of width, height etc, and since android devices are categorized as x, xhpi, xxhdpi etc, I thought dpi would be a good way to adjust their size but as you can see above this isn't the case.
An example case is: say if the device is small then I want a menu bar to take half of the screen and if it is large I'd want it to take only one third.
What would be a better way to adjust these widgets?
EDIT: If I use ConstraintLayout some of the buttons would have to be hardcoded with their size, but I want the buttons to get slightly bigger/smaller according to the screen sizes.
When your app app launch Find display's width and height.
Using this code, you can get the runtime display's width & height:
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
According to your height and width onCreate method to set component programmatically Like Button, Textview and others.
First, for your requirement of being able to use percentages, you can utilize a ConstraintLayout. I'd recommend the official training documentation to start. ConstraintLayout is relatively new (first release Feb 2017) so there aren't as many third party tutorials that are updated - but there should be enough info out to answer any questions you have to start.
Here's a short example:
<MenuBar
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintHeight_percent="0.5" />
For the second part of your question, you can provide alternate resources with different config qualifiers like xxhdpi like you mentioned above. More information on that here. To store a float value as a dimen in both the device form factors you want you'd declare in dimen.xml in res/values-[config_qualifiers].
<item name="bottom_menu_bar_height_percent" type="dimen" format="float">0.3</item>
Referencing from xml
<MenuBar
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_constraintHeight_percent=
"#dimen/bottom_menu_bar_height_percent" />
Hope this helps :)
I'm working on a Android App. Layout working fine on every device except where device screen size 480x800 & less.
How can create separate layouts by only targeting that screen size or less?
I'm already tried layout-hdpi, layout-small-hdpi & layout-normal-hdpi since phone like Nexus S, Nexus One are in hdpi category. But when I create separate layouts like layout-hdpi those layouts are affecting phone with bigger screen like Pixel, Pixel2, Nexus 5 etc.
Thanks in Advance
Phones (as opposed to tablets) tend to come in about three size groups (as far as Android resources are concerned): those with smallest width of 320dp, those with 360dp, and those with 410dp. The resources framework gives you a way to target any device larger than a certain width, so the correct technique is to put layouts for small screens on the default folder, and layouts for larger screens in one of the qualified folders.
Since it sounds like your layouts currently work well for anything 360dp or larger, you can make two layout directories:
res/
layout/
layout-sw360dp/
Put the special layouts for the small screens inside res/layout/ and put the “normal” layouts in the other directory.
Its not easy but you can also specify layouts based on the smallest width and you you supply the numbers. You can get more detailed and separate layouts that way however in my experience you will still run into that problem from time to time. In my current project using this method I have specific folders for W360 and W400 to deal with smaller devices for one specific screen.
https://developer.android.com/guide/practices/screens_support.html#DeclaringTabletLayouts
What you are looking for, is a layout bucket with the smallest width qualifier.
A layout with a set smallest width will be active, unless the smaller of the both dimensions (width or height) is lower than a certain value you can choose.
So, when a device has a smallest width below some value X it will use the default layout, when the value is X or more it will use the defined smallest width layout.
To create such a layout file in Android Studio, you wanna right-click your layout directory, click on new -> Layout Resource File and select the Smallest Screen Width qualifier from the list of available qualifiers. Now you need to specify your smallest width, which in your case should be slightly above 480dp. Give it the same name as your current layout file. Place your code for devices with a smallest width above 480p here. Now change the code in your other layout file, without the smallest width qualifier, to support smaller screens.
For further reference take a look at the official Android Developer page.
In my application, the layout must have a certain look but this is hard to achieve in many different screen resolutions and densities. I've read the developers article and tried my best to support many different screens by creating the following layout files :
However, 4.7" phones(1920x1080) and 5.8" phones(like my s8 : 1080x2220) use the same layout-sw360dp directory. Due to their difference in screen height resolution, the ui elements don't show up correctly for both phones. I want to know how i should go about solving this problem, can i use another qualifier to make android studio select the appropriate layout directory based on the phone's height or something? I'm starting to get lost here. Any help is welcome
After digging even deeper, i found out that you can choose different layouts inside the onCreate() method based on info from DisplayMetrics like so:
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width=dm.widthPixels;
int height=dm.heightPixels;
if (...) {
setContentView(R.layout.ex1);
} else {
// .....
}
By using the height and width variables as the conditions inside the if statement , i managed to select the appropriate layout files for each screen size!
I've a Photo gallery in my app. The set of pictures are stored in the drawable folder. I'm making use of ViewPager when the user swipes through the images.. What is the width and height in pixels and dps for xhdpi, hdpi, mdpi??
I know that the Android documentation says px = dp*dpi/160.. but I'm still confused about what should be the pictures download pixels so that it fits in all screen sizes??
There isn't one magic size that guarantees that it fits all screens perfectly. There are more than one screen size that fall under each density.
You should look at making your layout scale well on as many devices as possible. In your case it sounds like you shouldn't be focusing on an a specific pixel size, but rather how to display correctly on the common screens and gracefully display on less common ones. That being said I would do the following:
I'd look at the dashboard here. I'd make layouts targeting first targeting hdpi with a normal screen size(50.1% of the market) followed by xhdpi(25.1%) with a normal screen size, followed by mdpi(11%) normal screen size. Check table 3 on this page for common screen sizes for those values. Since you will be most likely using an image view make sure to check out the scale type attribute to help handle when the image view isn't at
As a side note(maybe useful later)if you are having difficulties translating sizes between densities and raw pixel values use this calculator.
Use following function which give you height and width of current display
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
deviceHeightPix = displaymetrics.heightPixels;
deviceWidthPix = displaymetrics.widthPixels;
based on this, you can pass data on server to fetch relative images.
I have searched for a while, to know which screen resolution i should consider before starting to design an android app.
I found these things:
xlarge screens are at least 960dp x 720dp
large screens are at least 640dp x 480dp
normal screens are at least 470dp x 320dp
small screens are at least 426dp x 320dp
Which device resolutions should be kept in mind when developing Android Apps?
but actually these are not what i wanted.
what i wanted to know is should i design my application for each of these resolution or take the most used resolution alone into consideration
or
if i am not using any hardcoded values for widths, heights and margins etc.., i never need to worry about the screen resolutions
or
how good is this - find the device width and height using Display metrics and create all views according to these values Dynamically ?
Should I design my application for each of these resolution or take the most used resolution alone into consideration.
You should make sure your application works correctly on all screens, not just the most popular one. I would begin from the bottom up... first make sure it works correctly on small/normal screens (and in doing so, you make sure it works on all screens). Then you can optimize your layouts for tablets by using multi-pane layouts, etc.
If I am not using any hardcoded values for widths, heights and margins etc., I never need to worry about the screen resolutions.
Not sure what you are trying to say here, but you should always be wary about different screen resolutions by using dp (density independent pixels) instead of px.
Find the device width and height using Display metrics and create all views according to these values dynamically?
This should be a last resort. Most of the time, your layouts won't be that complicated though, and it won't be necessary. A lot of the time you'll use wrap_content and match_parent to set the widths/heights, and often times you'll use RelativeLayouts to space the views relative to one another. You only really need to measure the widths/heights of the views if you find its absolutely necessary.
IMHO you should always code your application such that every device is supported. From the launcher icon which is detailed here (different resolution for different screen size): http://developer.android.com/guide/practices/ui_guidelines/icon_design_launcher.html to the layout of your app which should be designed so that everything is placed relative to the screen size (by using attributes such as match_parent and wrap_content).
You can try to code it such that the views are created dynamically after discovering screen size, but I think its easier and just as effective to do your first idea!
Best option is to get the screen width and height dynamically using simple height and width getting parameters.
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int wwidth = displaymetrics.widthPixels;
other option is to do create it for device with highest screen width and height and then handle it mathematically for respective screen size.
Well, it is recommended to design for all the sizes. But I know it is a lot of overhead.
So what you could do is design for the largest device you're aiming for and have the devices adjust the images based on their sizes. Do not use hard coded values. Use wrap_content or fill_parent.
And yes, dynamically adjusting the images is a good idea, even though it requires more coding on your side. This is the technique I use.