I have 12 basically identical views which I want to arrange in a grid that covers the whole screen. Depending on the device's orientation, I want to use a 3x4 or a 4x3 grid.
As far as I understand, there are basically three approaches to this topic:
Use a GridView
Use nested LinearLayout instances
Use a TableLayout
I'd like to have a layout that
automatically adapts to orientation changes (as GridView does)
uses all available screen space (as nested LinearLayout instances do)
doesn't allow scrolling (and without that "can't scroll any further" effect of the GridView)
allows me to force the same size on all of my items
By default, GridView has scrolling and doesn't fill the screen, whereas LinearLayout and TableLayout don't automatically adapt to orientation changes.
Currently I'm using a GridView with disabled scrolling and a custom adapter which sets the item views' minimum height depending on the orientation and the container's height to force a filled screen. This works but feels like a really ugly hack.
Dynamically constructing nested LinearLayout instances depending on the orientation would probably also work, although I haven't tried that.
This seems to be a frequent goal (1, 2, 3, 4), but all the suggested solutions are either as hackish as mine or don't satisfy some of my requirements.
As I'm new to Android development I'm not sure whether I'm missing something.
What is the optimal way of implementing this?
I'm targeting API level 8 and above.
Use a GridView
A GridView is a widget that you would use when you want to show data in a grid like manner with a larger set of data(as the GridView's recycling mechanism would provide a greater performance than a normal built hierarchy). This is not your case as you want all the views visible from the start and from my point of view the overhead of a GridView isn't simply worth it.
Use nested LinearLayout instances
A good option but avoid nested weights. You could use instead two LinearLayout with weights on the longest direction(vertical for portrait and horizontal for landscape) placed in a RelativeLayout with a centered anchor view.
Use a TableLayout
Another option. Use the stretchColumns option for the width and weight on the TableRows for the height.
Depending on the device's orientation, I want to use a 3x4 or a 4x3
grid. What is the optimal way of implementing this?
There isn't an optimal way, either of the solutions above could be used, you could also make your own layout.
Related
There is a dialogue, in one place of which I need to show either one element or another, depending on the situation. Example:
I would like to do this so that the elements below do not move. I want to keep the area occupied by alternating elements of a constant size.
What is the easiest way to do this?
I can, of course, manually change the visibility. Вut when switching, if there is a different height, then the underlying elements will jump. I can manually set their height equal, but this is inconvenient. It will be necessary to correct the heights of all alternating elements every time after I change one of them.
For example, Qt has Stack Layout that allows you to alternate elements and takes the size of the largest of them. Does Android have something like this?
You might be able to use the ViewSwitcher to hold the two layouts.
It holds 2 different child views and measures its height to the biggest child by default.
Here's the documentation for it: https://developer.android.com/reference/android/widget/ViewSwitcher
Just an idea if you can't find something like Stack Layout. I haven't tried it.
You can put all the elements in an horizontal LinearLayout with MATCH_PARENT width for the visible one and 0 for the invisible ones, but keeping all of them VISIBLE. It should always have the largest height and only the MATCH_PARENT width element should actually be visible.
With all the various screens sizes (both portrait and landscape) is it best to wrap conventional layouts (RelativeLayout, LinearLinear, etc) with a ScrollView if there is even the possibility of content extending below the screen? Is there a better approach?
Update Question: What about custom inflated Views? Does the same approach apply?
I don't think I would go as far as saying that wrapping every LinearLayout with a ScrollView is a "best practice".
That said, in my own experience, I have often created layouts that use ScrollView + LinearLayout even when I know that my content will fit on most phones. I've done this because (1) I want to support both portrait and landscape orientations (and landscape often does not have enough height to display everything) and (2) because I want to support any device my users might have (and some people do have really tiny phones).
The trick is to differentiate between cases where your LinearLayout is just chopping the screen up into pieces vs cases where your LinearLayout is a parent to some number of views each with their own fixed height. Two Buttons next to each other, each taking 50% of the screen width, obviously don't want a ScrollView around them. But a form of eight EditText fields on top of each other might do well to be wrapped in a ScrollView, even if all eight fit on your personal device's screen just fine.
The downsides to having an "extra" or "useless" ScrollView on larger phones is so tiny that I've never worried about it. A single extra View instance isn't going to hurt performance or use up too much extra memory. The upside of making your app usable on tiny screens, though, is well worth it.
There are few possible cases:
If your layout is a static layout, just buttons, text views etc., then you can just preview different screen sizes within Android studio and verify that the layout works fine for the devices you support.
If your layout is dynamic, like ListView, RecyclerView that gets dynamic data set, it is always a good idea to make ScrollView as the parent.
Does that answer your question? Please reply if further explanation is needed.
I am trying to build a row of images. I want the number of images to increase based on screen width. For example, in portrait mode there may be 3 images present, but in landscape there would be five.
I have tried using a GridView, but I am having trouble stopping it from being populated after the first row has been filled (it goes to the next row). Is there an alternative view I should be using or is a GridView the right approach?
If you only want 1 row, then use a LinearLayout. If it needs to scroll, embed it in a HorizontalScrollView.
If you aren't scrolling you can then inflate and add each image, depending on available space.
You could make it more complex by creating custom classes, etc.
You can also try the Two-Way GridView (I've used it - it works great)
How to make grid-view horizontally scrollable in android
I have found a suggestion based off of this. Once a max width has been exceeded on the LinearLayout, simply stop adding to it!
I've one of the simplest layouts imaginable: A num pad.
I want to create a fragment containing a 3 x 4 grid of buttons. The layout should automatically resize the num pad to fill the available space.
I've learned, that GridLayout is not up to the task, and TableLayout/TableRow or nesting LinearLayouts means nesting weights, which is also discouraged for performance reasons. A RelativeLayout won't work either, because that requires at least one button with given dimensions.
So, is there a clean way to create a regular grid that will resize to fill its parent?
Any help is appreciated, thx!
You will need a custom compound control.
Check the following link:
http://developer.android.com/guide/topics/ui/custom-components.html#compound
Make the control fill the available space. Make it to have 12 buttons. Calculate the size and position of them based on their position and the available space.
Depending on your needs you might also need to override onMeasure() and onLayout() defined earlier in the above document, in the "Fully Customized Components" section.
How to make multiple overlapped layout in android( for example I try to make two layout and make one layout to disable and other layout to enable for some operation, this layout overlapped with other layout).
You have a few options:
FrameLayout
This allows you to stack views directly on top of each other. This is nice and simple for some cases, but is limited. It will not help you align those views, simply stack them.
RelativeLayout
This is probably the best option, it allows stacking views on top of each other, but also allows for aligning views with each other. You can align edge, place views next to each other, or center in the parent. This is one of the most powerful views in Android.
AbsoluteLayout
This is deprecated and its use is discouraged. That having been said, this gives you pixel perfect view alignment if you know what the exact pixels should be. The reason it is deprecated is because Android devices have variable screen sizes and pixel densities, so more than likely when using this view you will be limiting your device support greatly.