I'm working on an app that retrieves news articles from the web and displays them.
The article contains different parts, text parts, images etc. so what I'm doing is parsing the article, creating Views (TextView, ImageView etc) accordingingly and adding them to a LinearLayout.
Especially on a tablet in landscape mode, this doesnt look good, so first thing which comes to mind is makes it 2 columns.
My question is: is there a library or a good piece of code out there that can do some if the work that is entailed with that, like measuring the height if the views I have added, choosing a good place within the content from where to switch to the second column, take care that the right column doesn't get deeper than the left one etc?
Pic for explanation.
Sorry, I misread your question, you're building the layout programatically.
As seen in this answer you can get the window dimensions like this:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
You can then figure out a threshold that looks good to start using multiple columns and make your views percentages of those sizes you measure.
There is not such a library since it is just supported by android system, but not in the your way.
We use fragments and flexible layouts for different screen sizes, it simple and powerful.
Try to read the following page for details.
http://developer.android.com/guide/practices/tablets-and-handsets.html
Related
I am migrating from Android to iOS (Swift). In Android UI elements are scaled up or down (height and width using "dp", layout_weight e.t.c) according to device size.
However I find this VERY difficult to achieve with Auto Layout's constraints, I want the elements in my UI to scale according to device size.
For example, in the shared image below, asides the compression of images to fit the screen width, every UI element has the same size, only looks like UI elements have been duplicated with same specs on all screens
This might help others in their migration from Android to Swift
(I only pinned the width of the 2 ugly ImageViews below)
P.S: This is what I'm trying to replicate guys, this view to fit properly on all screens. Sorry for the blur, I'm not in charge of this project
There's a zen to the AutoLayout. Let me see if I can give you some direction.
You'll want to test every UI on the smallest simulator available (iPhone 4S). This will let you know if you need to adjust your elements' minimum size.
Now for a top-to-bottom review of your UI posted:
"Profile" looks fine
To make the top-left and top-right boxes resize with screen size, you'll
want to give a constraint to the superview on left and right sides respectively. Then you'll want to make a horizontal constraint between the two (to maintain a space between them. Then you'll want to set them to equal widths. You can also set aspect ratio constraints for each one.
Your forms look fine. I can give more guidance here if the look you're after doesn't match the image you posted.
For the views below the form, you'll probably want to follow #2 above.
As for the height issue, set a constraint from your bottom view to the superview's bottom. There might be crowding, interface builder might yell. Chances are, you'll need to set the horizontal spacing constraints from = to >=.
I have a design that I need to follow in my app. In it there are several buttons, images and textviews placed all over the screen (some are aligned to the left, some to the right, some are centered etc). What I need to do is make all those elements appear EXACTLY as they are in the design image. The problem is, if I try to do this using dp, it can be wider or narrower than the design image specifies, and it depends on the properties of the screen. (I've had an app where I did it all in dp, and on my high-res phone it works perfectly, but on my friend's older phone it cuts away the edges of the activity)
My question is, what elements do I use for this? I've heard of using weight in Linear Layouts, but how to make items different width and height and position them all across the screen how I see fit? How to make sure it looks exactly the same on all screen sizes?
Thanks in advance! :)
Edit:
The point is, I need the buttons to be just as they are on the screen (this will be a listview element, I'm trying to make an xml for it). The distance, proportion, everything, it needs to scale to the width of the screen and be this size and distribution. And, I'm not just looking for a solution to THIS particular problem, I want to learn how to do it in general...
You don't. For very large and very small screens, you use separate layouts that scale the sizes, completely drop parts of the UI, or lays it out in a different manner. It's absolutely silly to think you can fit all the stuff on a 10 inch tablet and a 3.5 inch phone. If your designer expects that, tell him he's an idiot and he needs to get back to work.
For a more general answer on the best way of laying things out- it depends on the effect you're trying to get. You should never use pixel counts, and dp should only be used for small things- a bit of padding between 2 fields. Most things should be done via layout, either by using a linear layout and getting things in rows/columns, or a RelativeLayout and describing how to layout views relative to their siblings. But even with these tools you will not be able to fit on all screens and look good.
I'm aware that I can set different layouts for different screen sizes, but I would like to pull out the information of which one it has chosen. For example in the activity layout file for large tablets, I would like to add a view that scrolls through different statistical stuff, but on smaller phones this won't look good, and I'd rather have nothing there, as this will be a menu (i.e. fragments are overkill and will distract from the actual purpose)
So I would like to write some code which says something like:
if(xlarge) {
(manipulate stuff)
}
Is it possible to pull out the right constants from somewhere?
In your code, use findViewById to get a reference to the View that exists only in your large screen layout. If that reference == null then you know you are working with your small screen layout otherwise you know you've gotten hold of the large screen version.
If you really don't want to use Fragments for this, check out these links:
https://developer.android.com/reference/android/view/Display.html
https://developer.android.com/reference/android/util/DisplayMetrics.html
You could use the device's size like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
if (heightPixels > MIN_HEIGHT && widthPixels > MIN_WIDTH) {
manipulate stuff...
}
EDIT:
Just saw your comment to the original question. To get the screen size category, this question seems to answer it:
How to determine device screen size category (small, normal, large, xlarge) using code?
I'm using API 10.
I want to make my layout looking the same across all devices. I can achieve that by using LinearLayout with weights. It works perfectly. As seen on the image below, this is exactly what I want to achieve and it works perfectly:
But the problems that occur are two:
1)I get a warning of low performance because of nested weights.
2)I can't make animations out of bounds of the parent LinearLayout,
as shown in the image below:
So, I decided to make my layout with RelativeLayout. But the major problem is that I can't get the same layout across all devices, like LinearLayout and usage of weights. I spent two days searching for a solution and reading the ADT documentation. According to the documentation I have to make my ImageViews scaled to a factor of 3:4:6:8:12, to match the ldpi/mdpi/hdpi/xdpi/xxdpi. So I did: I created the corresponding #drawble folders, re-sized my buttons as the document says, and placed them inside the matching folders. The result is this:
This is a mess, it is totally unacceptable, for two reasons:
1) Screens may be of a certain density, for example hdpi, but they
differ from device to device of a certain screen size.
2) When I use the dp units relative to an element, for example: from
top of parent, the value I provide differs from screen size to screen
size. It is not by percentage like in LinearLayout.
So, where do I go from here? I concluded from my reasearch, that the only(or not?) solution is to make different layouts for different densities AND screen sizes. Like res/layout-mdpi-large/my_layout.xml and so on. But how do I calculate the dp for sizes and distances from relative components, based on the screen sizes? Do I have to resort to this list? Are these all the devices?:
Any tips, best practices, guides for the workflow, anything?
So I'm trying to write a game for android, and I have a couple of questions regarding 'best practices' for android dev. The game I'm writing would have some dice on the top part of the screen, which the user should be able to drag around, and on the bottom half of the screen, I need to show a list of different numbers, updating as the dice are dropped into a new location. So, what's the best way to tackle this? I've coded up some sample code (which works) using a single view, and drawing the dice bitmaps and the numbers, but everything is so resolution-dependent that it bugs me. Would I gain anything by switching to an xml-defined view, and adding a dice view and a number-list view, and drawing those separately? Is there a standard or best practice that I should be following?
Thanks
It is a good practice to define a Layout in xml file so that your app runs on different screen sizes..
For more on why you should be using xml files, please refer to Android Design Guidelines.
When using xml file use dp for sizes and sp for text sizes, also use wrap_content and match_parent where ever possible.
You can also make density independent pixels in your code. Please see this..
public float typedDimension(int a){
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, (float) a,
getResources().getDisplayMetrics());
}
Firstly, SurfaceView is a good choice for game development - it will give you much better performance than a standard view.
Secondly, a nice technique I have seen used is to write to a standard size off-screen surface and then scale that bitmap to the size of the screen. When you have screens of different size, everything will still be in the correct place. Note you should scale down rather than scale up, so you might want to use different sized images (for mdpi, hdpi, xhdpi) to avoid using too much memory on lower devices.