How does fill_parent in Android actually work under the hood? - android

I see great value in fill_parent, and I'd like to make my own implementation of it so I can do more than just fill the remaining space (ex: fill 80% of the remaining space, etc.)
How does fill_parent actually work under the hood? As in how does it compute the space remaining, how does it work at runtime, etc.
I've done similar things to fill_parent in the past where I calculate the space an element should take up based on the current screen size, how much of the screen the element should take up, etc. but I want to know specifically how Android does it with fill_parent.

Try creating a custom View or ViewGroup and you will find out.
There's 3 stages on bringing a View to your screen:
measure
layout
draw
In measure the parent tells the child how much space is available. It may do that in respect to the childs layout parameters. So if the child says match_parent (fill_parent is deprecated) the parent will pass in either its own size, or the remaining space (most of the time...)
The child then takes the available size, calls setMeasuredDimenstion(allTheSpaceIGot) and that's measuring for you.
Next up during layout, the parent checks the childrens measured sizes. It then sets the childrens bounds (top, left, bottom, right) accordingly.
Finally in onDraw every child draws itself within its bounds.
To sum this up:
Child gives parent information about its wishes.
Parent offers child some available space.
Child says "I'll take it".
Parent gives child its final restraints
Child draws itself within the constraints
If you want to assign say 60% to a view you should have a look at creating a custom ViewGroup (since that is who actually decides on the childs dimensions)
I also wrote a blog post about custom views that goes into more detail, followed by how to create a custom layout.

The entire source code for Android is open source, freely available within a few clicks on Google, so you can read it and study it all you want.
But just a fair warning, it's definitely no small task you're trying to accomplish, as there are an enormous amount of cases you have to account for.
If you want a layout to take X percent of available height/width, take a look at PercentageRelativeLayout
Just FYI: 'fill_parent' is deprecated, use 'match_parent' instead. They literally do the exact same thing, it's simply a different word.

Related

Android: an easy way to alternate UI elements in one place

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.

What exaclty is the meaning of MATCH_CONSTRAINT?

I am new to Android and recently I came up with a term 'match constraint' while using ConstraintLayout.
As per doc it says 'Dimension will be controlled by constraints', I don't understand what exactly mean by this ?
As far as I could understand , it's somehow can be used as replacement of match-parent but not sure how ?
First of all, lets look at what the word Constrain means. According to Google, Constrain means to
Compel or force to follow a particular course of action
Severely restrict the scope, activity or extent of
Bring about by compulsion
When using ConstraintLayout we align/position our items by applying Constraints to that particular item. What these Constraints do is that they limit (or allow) the position of that item in the screen. Lets say I have a button which I constrain to be between the left and right edge of the screen. By doing so, the button can move anywhere in the screen as long as it is within the left and right edges of the screen. Similar is the case if I constrain the button to be between the top and bottom of the screen.
Now what does MATCH_CONSTRAINT mean? It means, that the view will take up as much space as the Constraints allow it to take. So, if I constrain a view to be between the left and right edge of the screen, then the view will expand its width to be equal to the width of the screen (if no margins are set).
It means it will take the available space in the main constraint layout. For more details, you can read it from here

How to create a regular, resizable grid without nested weights?

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.

Android: Getting blow-up in landscape mode, but not in portrait mode

I've got a situation where I bring up a color picker. If it's done in portrait mode everything is fine. But if I do it in landscape mode (the dialog doesn't fit on the screen) it seems to be blowing up when trying to inflate the layout.
Is there some special way to do this in landscape mode where the view doesn't fit entirely on the screen?
Any differences I need to take into account other than screen real estate?
CraigA,
After reading your comments, it seems there is a misunderstanding about the way that different widths and heights are generated in XML. This is a common misconception at first. So, the thing to understand here is that the width of the various objects, while dynamic, impose different behaviors upon your objects.
layout_width/layout_height generally
The width and height parameters do not affect the actual width and height of the object. They affect the display width and height. This means that you can set the width and height to smaller than the contents, and the contents will still be accessible when scrolling, if they are bigger than the container.
Since many child Views take their cues from the parent Views, this can result in behavior like you are seeing above. The trick here is first to understand what is going on, and then compensate for the behavior of the system.
match_parent/fill_parent
Ordinarily, this means that the current View will get its size from the parent. If the View is a top-level View, the behavior changes slightly. If this happens to be the top level View of a Dialog, then it will be the size of the screen or the size of the contents (whichever is smaller). If the View is the top-level View of an Activity, then the results are the same, but they look different. That is, it will have the full Activity opacity and background, but the View's size is only that of the contents or size of the screen (whichever is smaller). The children's sizes are unaffected unless their width/height is based upon that of this View.
wrap_content
In this case, the display height is based upon the display heights of all of the immediate children. This behavior cascades down to the "youngest" descendants until the hierarchy uses something other than wrap_content.
Your issue (as it appears right now)
Your top level view uses wrap_content, so the display size will be based upon all of the children's display sizes. In this case, it might be better to use match_parent' orfill_parent` (depends on your API) for your top level View only. This will at least get the Dialog to be the appropriate size, if not the contents. For those controls whose size is based on the top level View, they will come into line. Those that aren't will have to be adjusted manually.
Now, the decision you have to make here is implementation. Do you need to adjust the sizes for every display, or just the landscape. If your changes have no effect upon the portrait display, then one file should be good. If not, you will want a layout file for portrait (the current one), and then an adjusted one for landscape mode.
If you are using two files, you will have a folder named layout_port for the current one to be stored. You will add a folder named layout_land for the adjusted one. They will be of the same name, just housed in the separate folders.
Hope this helps,
FuzzicalLogic

Two-pass UI Layout : Why?

I've noticed that Android, WPF, and Silverlight all follow a two-pass layout pattern. There's a recursive Measure() method that gets called to size the element, possibly multiple times. Then a recursive Layout/Arrange() method is called which lays out the exact positions of children in their parent control, and will also set the final size of the control.
My question: why is this split into two passes, especially when, for some types of controls, Measure() can't compute the actual size of a control without actually laying out the positions of the children? Is there some type of layout minority case that is made possible by this?
I'm trying to create my own UI toolkit, and I'm currently leaning toward a one-pass Layout() pattern, but I'd like to be convinced whether this is wise or not.
Thanks for reading this :)
Sean
The reason for the two passes is that any element in the structure can influence the remaining available space of the others.
Some element wish to take the largest possible space while others have fixed dimensions. You can also have elements with only a max width set. It creates an equation that can not be solved in one pass.
The different panels in the hierarchy ask the elements what size they need in the first pass, then distribute the space among them according to each panel's nature, and finally informs each element of its allocated space.
EDIT: Some more explanations
The main drawback of a single pass layout is that you are handling each element sequentially. A first element takes a certain amount of space and the others take the rest. Why is this element the first? Try your algorithm with different element order, and you will have different resulting layouts.
A two pass layout simulates a parallel behavior where each element influences the whole layout.

Categories

Resources