Scale drawable in Android to support multiple screens - java

Currently I seek a solution to simple situation, which appeares to become tricky. I need 7 togglebuttons in android app, which are a simple black circles, but I need them to be in the row and fill parent (screen) horizontally. As a resource I use big .jpeg image of a circle. To make them fill all screens in the same mode, I put them into LinearLayout with
#android:layout_width = "fill_parent";
#android:layout_height = "wrap_content";
#android:weight="70";
Weight is 70, so each button received 10. The problem is that source image is too big, which unfortunately results in...this:
(because I dont have enough reputation for posting images, here is the link
http://postimg.org/image/f8wvs5si1/ )
Sorry for small amount of code and this picture taken via phone, I do not have an internet access on the computer with eclipse and this project for some time. I tried of course to change layout_height on other possibilites, but it didnt work. I could put a weight sum also on the vertical position, but on different screens it wouldn't look same.
I also tried to change the height programmatically in onCreate method,
buttonX.setHeight(buttonX.getWidth());
or do the same with a layout, but nothing helped
Perhaps the question is dumm, but I would be glad to hear some ideas.

This is due to screen density variations. There are several things you can do to fix this:
Use different images for each density (but I'm assuming you're looking for another solution)
Use DisplayMetrics to get the actual width of the screen and then set width/height accordingly.
This code:
buttonX.setHeight(buttonX.getWidth());
probably doesn't work because you are calling it before the layout is drawn, and therefore the width is not the drawn width. You can fix this using ViewTreeObserver like here:
How can you tell when a layout has been drawn?
Use an XML attribute like scaleType="centerFit" Personally, I find these confusing because scaleType attributes don't always seem to behave the same way to me. You might have to try different ones, but sometimes they come in handy if you need an XML only solution.

Related

Programmatically set a percentage height to LinearLayout in a Widget's RemoteViews

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)

How can I make the width of a Constraint Layout negative?

I'm not sure if this is possible, or If I am approaching this challenge wrong. I am making a 2D Platformer, so when you hit the edge of the screen(Width), a new portion of the map would appear. Currently, I made single Images for each Portion of the map. Problem is, on larger devices, this would leave a lot of blank screen, and the Image would only fit a specific device.
Now I am wondering, can I make my ImageView (MAP) at a negative X value then when the character hits the edge, the map would move right (X would go higher).
I am using XML (Java is also fine), and I have NO CLUE how to approach this.
Since you are using constraint layout, you need to set android:layout_width="0dip".
This will fit any image to its screen width.(Image width should be greater than screen horizontal width).
Apply some conditions something like,
If image width < screen width then call next image to remaining screen, else call next image for entire screen.
Hope it helps for code-flow.
:)
You could use android:translationX or Android:translationY which actually support negative values. But in your particular case I think you are trying to use a nail clipper to cut your hair... You are using stuff that are not designed for that purpose. Using multiple big Image views can become a performance issue (I don't know about your particular case), I recommended you instead to be brave and make your own wiew and paint it dynamically (it can sound difficult but I'm sure will be easier than what you are trying), or make a comprehensive googling for a view meant for what you want.
Specifically for games you should try andengine lib or something like that, believe me... It would be easier in the end and you may earn something new :)
An alternative solution is to draw a layout (e.g. RelativeLayout) larger than your screen size, with an equal amount of padding on all sides.
For example, if you want to make a 50dp x 50dp ImageView appear from off the right hand side of the screen, your RelativeLayout would be 100dp taller and wider than your screen (50dp on each side). You could then position your ImageView at the far right of the RelativeLayout, and move it onto the visible area at will. So drawing something at -20dp, would actually be drawing it at 30dp in this example.
Programmatically getting the screen size and resizing a layout is very straightforward, and this approach would let you control your map loading in the manner you described.

Android - Text positioning

I have a very, very, very simple application that I'm working on (been trying my luck at writing an app in Java instead of Unity) and I have a background image that is fullscreen, this image has a lot of design and scales well with every device, and looks great (tested on every resolution we can think of).
However the text doesn't want to stay where it belongs, and that's not permissible. We have a basic setup, similar to this (however with about 6 hours of design work put into it):
and we need text to be centered in the squares at all times. How can we do this? Do we have to manually position and size it for each resolution? That seems like hell.
With a relative layout, if I understand correctly, the boxes will be parents and the text that goes into the boxes will be the children. You can put your TextViews into the boxes and then use things like android:layout_centerVertical or android:layout_centerHorizontal in order to make sure they are centered. Make sure to use sp for your font size so that it scales correctly with the density of the display.

Android Confusion on supporting multiple screen sizes

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.

java android - fit items on a image background with different screen size

This is my first post and i have (i think) a uncommon request...
I'm programming on the last Eclipse Mac, for every android SDK, and i'm using more XML for layout than runtime... So i search a solution in XML if possible.
Here is the situation: i work with an image background wich simulate item like buttons, image, text... etc. On this image, i put buttons, image, and text (buttonview textview etc...) and place it precisely on their places on the image. This solution is very powerful to have good design BUT, if i change the resolution of the screen, and/or its size, each item won't be at its place, and will be translated (horiz and/or vertic) for some "dp"... (and yes i use dp, not mm or px or whatever)
I'm really embarrased because i think thanks to "dp" it keep proportionnality but.. not !
My question is how can i fix my items at their places on the image background, for different screen size/resolution !!
Thanks in advance everyone,
My Best From Lyon,France
First realise that if you want to make it pixel perfect for all screen sizes your out of luck.
Second accept that you can't make it perfect for all screen sizes.
Third you can get far with creating different layout for different screen sizes. You can read a lot about supporting multiple screen sizes here. One important thing to take from here is that you can make layout for the different screen sizes or different density sizes.

Categories