I'm a newbie in mobile development and I try to develop an Android application for several models of smartphones and tablets.
Now I'm experiencing some problems with selecting an appropriate layout parameters for Xiaomi Redmi 6a [https://www.gadgetsnow.com/mobile-phones/Xiaomi-Redmi-6A]
I designed a layout specially for it : land-xhdpi-1440x720
But when I try to run my app it seems to be, that it selects land-xhdpi-800x480.
Why so? What Am I doing wrong in this case?
And, by the way, could you recommend me some articles about layout selection for different types of devices based on some real experience (not an Android Developers Manual)?
It's considered bad practice. Why do you need layout for particular device?
Screen dimension for resource qualifier is set in dp, not in pixels. For xhdpi screen with 1440x720 px, screen size will be 720x360 dp
According to the layout folder spec it does not appear to allow specifying both screen dimensions in a layout folder name.
If you want to check the device model in your app you can use the Build class (the BRAND, MODEL and DEVICE fields) and select the appropriate layout at runtime by calling setContentView(R.layout.*) in your Activity/Fragment.
However, you should be aware that matching the device model to the screen resolution can be challenging, especially since on some phones the resolution can be changed in settings.
It would be safer to check the actual resolution at runtime:
DisplayManager mgr = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE)
Display[] allDisplays = mgr.getDisplays();
Display targetDisplay;
if (allDisplays != null && allDisplays.length > 0) {
//select the display to use, usually there is only one (or find the one with the highest resolution)
targetDisplay = allDisplays[0];
//get the resolution
Point sizePt = new Point();
targetDisplay.getRealSize(sizePt);
//or
DisplayMetrics metrics = new DisplayMetrics();
targetDisplay.getRealMetrics(metrics);
}
Also note the actual values may not be equal to the physical resolution due to the height of the notification and navigation bars so be sure to run some tests and try to use more general comparisons than
sizePt.x == 1440 && sizePt.y == 720
Related
I want to create a widget with graphs which represent a percentage increase in stock value for certain assets. I was able to create an overview of graphs with each graph having a percentage height by putting two LinearLayouts in a container LinearLayout. The bottom LinearLayout is the graph and the top LinearLayout is the spacer which gets a certain layout_weight. This way I can reduce the size of the other container using percentages. (if the spacer has a layout_weight of 0.4, then the graph is 60% high).
The current state of the widget is (I wanted to handle negative values in red afterwards, but no need to continue if I can't figure out how to percentually size the graphs) :
I chose this approach because I can't use ConstraintLayout in RemoteViews. Everything seemed to work nicely, but when I wanted to programmatically change the size of the spacer based on data from the api (so the sizes of the graphs truly match the percentage increase of the stock value), I wasn't able to. There is, as far as I could see, no way to change the layout_weight of a LinearLayout in a RemoteView in java.
I then thought maybe my last hope would be to find the container - which contains all the graphs - its height by using findViewById, but that's also not possible with RemoteViews. I then would've seen the container's height as 100% and then set the height of the other LinearLayouts according to that size. 60% would be 0.6 times the height I fetched from the container. But that, I'm afraid, is also not possible.
So I actually have no clue how to programmatically find out how high a LinearLayout is or how I can change the size of a LinearLayout percentually. It seems like I always already need to know the sizes of the containers which will be used in the widget? Which is kind of annoying as the content varies and it needs to be rendered differently based on the ratio of each gain of each asset.
Am I missing a certain way to approach this? I can't seem to find much more on the Android Developers documentation... Cheers!
The ability to affect things like that was only added in API Level 31 (Android 12), with methods like setViewLayoutHeight(). So, one option would be to set your minSdk to be 31 and live with a smaller user base for a while.
Or:
For a complex UI, you might consider rendering a Bitmap inside your app, then showing that Bitmap in an ImageView in the app widget (with the Bitmap served via a ContentProvider). This is annoying, but it gives you ultimate flexibility.
Another possibility is to have a bunch of different layout resources, where you encode a range of desired weights, the use the desired one in the RemoteViews when you go to update it. If you keep consistent widget IDs, the rest of your code should not need to change much.
You have the question tagged as java. If you eventually learn Kotlin, you could see if Glance has some more flexibility. Glance uses Jetpack Compose to create app widgets (and Wear OS tiles).
Use directly :
view.setViewLayoutHeightDimen(your layoutId, int heightDimen)
Some info
I'm trying to optimize my app for a 5.1" device, actually i have a layout and a large layout ( optimized for a 7.0" ) but if i try to put as device a device with 5.1" instead of changing the size of the main layout it open and change the large layout size...
Question?
So the question is, how can i create a layout with a custom size? I would create a layout-normall if it's possible and set it to a 5.1" because also the main layout is optimized for a 5.0"...
PS: (i'm yet using ConstraintLayout and it's not working on switching device )
pic releated :
It sounds like you are using the Screen size resource qualifiers to supply your alternate layouts:
/res/layout/mylayout.xml
/res/layout-large/mylayout.xml
I recommend that you stop doing this, and never use screen size resource qualifiers in the future. As you've noticed, the difference between "normal" and "large" is unclear, and plenty of phones count as "large".
You're much better off using Smallest width resource qualifiers:
/res/layout/mylayout.xml
/res/layout-sw360dp/mylayout.xml
/res/layout-sw600dp/mylayout.xml
Providing your alternate resources in this way gives you precise control over when a particular layout is used. Note that you can use any number here; sw487dp is totally valid.
You can read more about it here: https://developer.android.com/guide/topics/resources/providing-resources.html
The smallestWidth of a device takes into account screen decorations and system UI. For example, if the device has some persistent UI elements on the screen that account for space along the axis of the smallestWidth, the system declares the smallestWidth to be smaller than the actual screen size, because those are screen pixels not available for your UI. Thus, the value you use should be the actual smallest dimension required by your layout (usually, this value is the "smallest width" that your layout supports, regardless of the screen's current orientation).
Some values you might use here for common screen sizes:
320, for devices with screen configurations such as:
240x320 ldpi (QVGA handset),
320x480 mdpi (handset),
480x800 hdpi (high-density handset)
480, for screens such as 480x800 mdpi (tablet/handset).
600, for screens such as 600x1024 mdpi (7" tablet).
720, for screens such as 720x1280 mdpi (10" tablet).
Even though I don't know why you would want to, but if you did want to make this app to fit only one screen size, you can use the AVD manager. Go to Tools --> Android --> AVD Manager. Then create a new virtual device with the dimensions you want.
You don't have to use this virtual device, but if you create a new one with the dimensions you want, it will appear under the drop down you have shown in your first picture at the very bottom of the spinner.
I am creating different layouts for different screensizes using the layout-sw<>dp qualifier, but for some reason, it is not working. I have the following layouts:
I made a special sw320dp directory so that it looks nice on one of my test devices which was 569 dp x 320 dp. Then, for my LG-G3, which is 480 dp x 853 dp, I made the layout-sw480dp folder.
However, the 320dp layout is showing on both phones, including my LG G3.
Am I doing something wrong? Shouldn't the 480dp layout show on my LG G3? Please let me know.
Ruchir
This link tells to consider actual sizes that are available to your activity's window when choosing qualifiers
The smallestWidth of a device takes into account screen decorations
and system UI. For example, if the device has some persistent UI
elements on the screen that account for space along the axis of the
smallestWidth, the system declares the smallestWidth to be smaller
than the actual screen size, because those are screen pixels not
available for your UI.
so ensure you have at least 480dp available to your screen and it is not partially taken up by any system UI/ screen decoration.
Ive read Android documentation on the subject of supporting multiple screen sizes but I just cant seem to wrap my head around it. I know qualifiers need to be set in layout names and android picks the one whos qualifier is closes to the width of the phone.
Im not to worried about tablets at the moment but when I develop for my physical device everything is fine and dandy all in default layout folder: layout/main.xml
But if I test on my friends phone Samsung Galaxy S4 everything is streched in a vertical way. I just dont know where to begin really...
Is there a standard set of folders that I could implement to lay my layouts in and then edit for optimized performance?
http://developer.android.com/training/basics/supporting-devices/screens.html. It's all explained in this tutorial link.
If one layout should support all screens then,
your app theame should be similer for tabs and mobiles
never use fixed values for layouts like (ex:300dp , 15dp), all are wrap , match , fill depends on requirement,
make all the icons, images in 2 or 4 different sizes
NOTE: if you have minor changes for smaller to larger device ui, then in on create get the device height and width , make your changes (images, layout widths etc..) runtime from java
If your app is not similer from small to big devices
Use layout(mobiles) ,layout-large(7 inch tabs) layout-xlarge(10 inch tabs)
Start with device independent pixels (dp) and scalable-independent pixels for fonts (sp)
If something is stretched vertically after that, it probably means it's a background image that's trying to fill up the entire height of a layout (by the way, next time you have a problem, please do post the relevant xml code and dimensions of the image, or at least a screenshot of the problem).
In that case, just use the different size qualifiers to solve your problem (not your density qualifiers). Density qualifiers don't help for widths or heights of bitmaps that are larger than the widths or the heights of device screens. This is just a rule of thumb that you should be aware of.
Use the toolbar select box in the layout designer of Android Studio/IntelliJ to quickly test multiple device screens all in one go. This is the fastest way to do it. Do not use Eclipse for that, its ADT layout designer doesn't have that capability (at least, not the last time I've checked). Even if you use Eclipse most of the time, it's worth using Android Studio/intelliJ just for that functionality, and then switching back to Eclipse (assuming it's still your favorite IDE after that) when you're done with testing that aspect of the layout.
Also, don't try to do a different layout for each size qualifier that you encounter. Only use different size qualifiers for the layouts that are actually giving you problems. And don't forget that common layout components that don't need to be duplicated can just be abstracted away in a parent layout. And if you can find a way to resolve your specific problem without the use of size qualifiers, that can work just as well. For instance, if instead of using a single image for your background, you could replace it with a larger image that you don't mind getting clipped at different aspect ratios, or replace the background image with something entirely different and abstract (like a solid color, a gradient, a tiling background, a large vector graphic, or a large patch-nine png) that looks ok at different aspect ratios, that could be even simpler still.
At the high level, you just need to take care of these things:
- Better have the images sliced for either XHDPI (720x1280) OR XXHDPI (1080x1920) resolution and keep them in respective folders. XHDPI images into drawable-xhdpi and XXHDPI images into drawable-xxhdpi folder. One set of image slices are enough.
- You don't need to write different XML layouts for the same screen if you are not supporting Tablets (except for very rare times)
- Try to avoid hard coding the android:layout_width & android:layout_height parameters. Use wrap_content, fill_parent OR match_parent.
- Try to avoid keeping any image slices inside simple drawable folder instead keep inside specific drawable folders like drawable-xhdpi , drawable-hdpi etc.
- Try to use, color codes & 9 patch images as much as possible instead of using images for everything which will reduce the build size and also helps in avoiding OutOfMemoryException.
- Inside simple drawable folder, keep all your XML drawables like background of a button with separate images for clicked & focused states etc.
If you follow these steps, you don't need to worry about supporting multiple screen resolutions for most of the cases.
I am attempting to design an app which reproduces the shortcut styles of the standard app shortcut home screen icons but as a widget. Note, this is currently just looking at the standard Android homescreen.
I have made the following observations using the "Dump View Hierarchy for UI Automator" tool in the DDMS -> Devices view of Eclipse:
The space given in the 1 x 1 square changes depending on screen density, orientation and whether the phone home screen is in "phone mode" or "tablet mode" (start a 4.x emulator and you can tell by the background amongst other things). Screen density effects the size as expected (0.75, 1, 1.5, 2.0 density factor scaling), but the orientation and 'home screen mode' are quite unpredictable. Specifically:
DIMENSIONS FOR A 1x1 'SQUARE' ON THE HOMESCREEN
Phone mode:
Portrait: 80dp x 100dp = 4:5 aspect ratio
Landscape (if available - not thoroughly tested): 106dp x 74dp = 53:37 aspect ratio
Tablet mode:
Portrait: 96dp x 96dp = 1:1 aspect ratio
Landscape: 96dp x 96dp = 1:1 aspect ratio
As you can see, there is barely any consistency whatsoever, but these are the dimensions given to a 'square' on the home screen. It gets even worse when looking at the space actually given to widgets (yes, it does differ from the square space available and used by the system shortcut widgets):
DIMENSIONS GIVE TO A WIDGET IN A 1x1 'SQUARE'
Phone mode:
Portrait: 80dp x 100dp = 4:5 aspect ratio
Landscape (if available - not thoroughly tested): 90dp x 58dp = 45:29 aspect ratio
Tablet mode:
Portrait: 72dp x 72dp = 1:1 aspect ratio
Landscape: 72dp x 72dp = 1:1 aspect ratio
So I'm stuck with:
Inconsistent aspect ratios between phone and tablet modes
Smaller areas given for an app widget then that of an app shortcut in some cases. Consequently, the relative and perceived size of widgets will look very different on a tablet vs phone?
The smaller areas aren't even vertically centred, they are mostly top aligned with a 2dp top margin which means they don't even look aligned with a neighbouring application shortcut to start with, let alone when trying to produce a similar looking shortcut through a widget
To visualise, the following images show a default system shortcut (with a red box surrounding showing the 'square dimensions - which both system shortcuts and widgets always share). Next to it is my widget with the blue highlight showing the bounds of a MATCH_PARENT setup, hence where the widget can actually draw within its 'square':
Phone - Port:
Tablet - Land:
Tablet - Port:
Most important to take from here, is the blue area of the widgets on a tablet does not even include the space where the system shortcut draws its text?
Does anyone have insights into:
Why the home screen is so inconsistent?
Why app widgets are not given the same drawing space as that of a system shortcut / or should it be and I am doing something wrong?
Should I be doing something else, or is it just accepted that for a 1x1 widget which takes up all its given drawing space, it will look 'smaller' (compared to its surroundings) on a tablet than it would on a phone?
And even better, many launchers allow the user to customize the size of their grid. Per the design guidelines for App Widgets, you cannot rely on an exact size on all devices. Instead, determine a minimum width and height and let the home screen determine how many squares the layout takes up.
They do provide some guidance on what you can expect for the minimum size of a cell (and all your numbers are much larger than that it seems), but again custom launchers may reduce this minimum even lower.
I find it best to focus on what components need to be in your layout (buttons, etc) and then follow the Metrics and Grids design guidelines to determine your minimal size (noting the margins are automatically added on Android 4.0+ devices but not on <4.0 devices). Then make sure your layouts are dynamic enough to fill in the space provided to them (centering text, etc as appropriate). Remember widgets are assumed to be a framed, single entry, rather than floating text as noted on the App Widget Design guidelines.
Hey you can manage the scree sizes in layouts you want to create different layouts for different screen sizes and also for landscape and portrait .
create the following layouts in your resource folder like this :
layout-large
layout-small
layout-xlarge
layout-landscape
And then copy your XML files in to it and check in preview screens for different devices you can have a idea based on that you can modify the size of the widgets in your homescreen.