I created a custom layout which can have an arbitrary amount of child views.
I figured out that the child views are not available when I try to access them in the constructor of my layout view.
So what I currently do is to access them in onMeassure, but it seems to be a bad idea, since this gets called several times.
What is the best place in my layout to init child views? I wish there was a method like onChildViewsAttached(). Any ideas?
Child views are attached to the parent once layout pass is finished, i.e layout() of the view group is finished.
You can also register OnGlobalLayoutListener or OnPredrawListeneron the ViewTreeObserver of your custom layout.
Related
I am new to Android Development, so what is meant by child in the below paragraph....
A ScrollView is a FrameLayout, meaning you should place one child in
it containing the entire contents to scroll; this child may itself be
a layout manager with a complex hierarchy of objects. A child that is
often used is a LinearLayout in a vertical orientation, presenting a
vertical array of top-level items that the user can scroll through.
https://developer.android.com/reference/android/widget/ScrollView.html
In android (and most other technologies), views can have subviews, aka "children". Most views can have children and can be a child of a parent view. It's kind of like a "tree".
The most obvious feature of being a child of some other view is that the child moves with the parent view. Another feature is that the child is in the coordinate space of the parent view.
Your paragraph here basically says you can only put one child view in ScrollView and it is usually a LinearLayout. But don't be fooled! This child can have its own child views.
Gaurav i think this is what you looking for, you need to use only one LinearLayout tag inside ScrollView tag, if you are using more than one LinearLayout than it will show error. If you want to use more LinearLayout tag you can use them inside LinearLayout tag which is inside ScrollView tag. May be this will help you.
You need to understand the general concept of child and parent . Simply you can think of the real life relation between parent and child.on the hierarchy parents are toplevel and child is below.so when you come to android layout parent is container and child is the content.
I have a child linearlayout created programmatically and added on a parent linearlayour programmatically.
parentlayout.addView(childlayout)
But, the I want to add again the child layout to another linearlayout, it returns an error, is it possible? What is the best way to do that?
Create another instance of the same class, and set the same properties. I mean Inflate your View again if needed. Because A single View cannot be a child of two ViewGroup parents.
Each view can have only one parent possible.
So you can not add same child to another linear layout.
What you can do is make another instance, apply same properties which you given to previous child. and then add this instance to the parent view.
I have a custom view in android which is also a container for other views. The child views have certain onClickListeners attached to them. My question is when the parent view is dismissed, does the associated child views and their corresponding listeners also cleaned up or do we need to handle it separately?
Basically any View can be considered as ViewGroup hierarchy with child elements in it. If by "dismissed" your custom View is removed through the call of ViewGroup#removeView (or any similar removal methods) then all its children are removed too.
I have a ViewGroup that can have many LinearLayouts. And each LinearLayout can have many nested child views. What I want is that, if any view(even deep nested) inside a LinearLayout gets focus, it should call a custom method of its main parent LinearLayout.
The last thing I want to do is, set OnFocusChangeListener on every single deep nested child views of LinearLayout and that listener will call its parent's custom method. But that is really bad way to go for.
Is there any method I can override of parent LinearLayout that gets called every time its any nested child view's focus changes ?
You could use contentView.getViewTreeObserver().addOnGlobalFocusChangeListener() or override ViewGroup.requestChildFocus() of the root ViewGroup (requestChildFocus() is passed along the view parent chain).
For example When we write the code
View view = inflater.inflate(R.layout.main_activity, null);
What does the Android system do?
Check out the source for the LayoutInflater. It's an abstract class, a concrete instance of which is obtained through getLayoutInflater().
In essence, the inflater creates a root view object (the root view group of the inflated XML), then does two passes through the XML tree to attach each child view. This is done recursively to handle 'include' and to fix up references between child views, for example in RelativeLayout, and is done top to bottom.
The first pass constructs the tree by instantiating each of the child views, top down recursively, and passes the XML attributes to the view constructor telling the view how big it should be. It then calls measure() for each child passing in restrictions determined by the parent (e.g. RelativeLayout with 2 child views each requesting match_parent) using a measure specifications object and asks the view how big it wants to be. If the view is itself a view group, it will use the same algorithm to measure it's children.
The second pass is the layout pass when layout() is called on each child to position itself within the view. The parent positions the view using the measurements calculated in the measure pass. onDraw() is called and is passed a Canvas created from the DecorView backing bitmap.
The finalised tree is then ready to pass to the window manager which is done by setContentView() or addContentView().
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/view/LayoutInflater.java#LayoutInflater
Inflating an XML layout in simple language means you are converting the XML in View. Then you can fetch each view declared in the XML using the parent/inflated View.
For eg -
View view = inflater.inflate(R.layout.main_activity, null);
Now, here view is the reference of the XML from which you can fetch all the views as,
TextView tv = (TextView)view.findViewById(R.id.tv);