How to recursively iterate through ViewParent tree? - android

I have tree of views, looking something like this.
-- parent view top
-- parent view mid
-- parent view mid
-- parent view low
-- parent view low
-- child 1
-- child 2
-- child 3
I want to check from the child level the id of the top parent view to apply some logic there, based on some TouchEvents in child.
Do you know how can I design the recursive function which will allow me to iterate to the top?
I was able with the usage of getParent() method to get to desired Parent, but this solution is not flexible enough for me at this moment.

A recursive function from child to parent can be done in this way.
public void doSomething(View view) {
//
// do something here
//
if(view.getParent() != null)
{
doSomething(view.getParent());
}
}

Related

getViewTreeObserver for 2 views

Haven't found something to understand how to use it correctly.
I need to measure 2 views.
For first view i use this:
viewPager.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
//my measure code
viewPager.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
So what should i do for second view: i should use another same block of code, but for second view or can i put second measurement inside viewpager's measurements?
Added: logically it can be different cases:
One view inside another view.
Two views near each other in same parent (viewObserver on first view).
Two views near each other in same parent (viewObserver on parent).

Android - Move a single instance of a View between Parent Views

For an important reason, i'm required to keep only a single instance of a View in the entire application.
Within the application there will be multiple parent views, (each displayed only once at at time). And I need to move the child view around - to the currently active parent.
I tried doing the following:
if (view_to_move_around != null) {
ViewGroup oldParent = (ViewGroup) view_to_move_around.getParent();
if (oldParent != null) {
oldParent.removeView(view_to_move_around);
}
} else {
// Initialise the View
}
newParent.addView(view_to_move_around)
However, that method didn't seem to work? Completely stuck at this point.
I guess my question will be "What do you mean it's not working?" Are you getting an exception? It is not being displayed properly? Does it execute without issue, but is not displaying? Does it display, but it's always initializing?
Are you manipulating the child view within each parent view, before you pass it on to the next view?
Few things to make sure right off the bat:
Layout Params. Are they all set correctly? For both the parent and the child?
Parent View. The code doesn't appear to be faulty from what I can see. So is the parent view being displayed correctly?
Visibility. Are both the parent and child View.VISIBLE?
EDIT
Sweet. Ok, when I'm debugging these things, I like to keep it simple at first. I would take the child view, set it's background color to purple (or a contrasting color from the parent). Then, for simplicity's sake, set it's layout params to match parent. Assuming the ParentView is a FrameLayout:
mChildView.setBackgroundColor(Color.CYAN);
mNewParentView.addView(mChildView,
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT, Gravity.CENTER));
Does it fill up and take over the parent?
In the intermediate steps, does it no longer have a parent when it's been removed?
Log.d("LOGTAG", mChildView.getParent().toString());
Does the new parent show that the child has been added?
Log.d("LOGTAG", mNewParentView.getChildCount()): // before and after
Is it being shown 'behind' the other views within the Parent?
mParentView.bringChildToFront(mChildView);
What may be the problem is that you are using getParent() to store oldParent. Compare for example:
if (view_to_move_around != null) {
ViewGroup oldParent = (ViewGroup) findViewById(R.id.old_parent);
if (view_to_move_around.getParent() == oldParent) {
oldParent.removeView(view_to_move_around);
}
} else {
// Initialise the View
}
newParent.addView(view_to_move_around)
Does this sound like what you're looking for? Let me know if this works.

RelativeLayout check runtime if is removed or not

In an activity I am changing one of the ViewGroup content runtime: buttons action, other events.
At a specific case I need to check if a child is in this layout or not ( in this case the child is another RelativeLayout, which hold other views)
How can I check runtime, programmatically if child_1_RelativeLayout is there or is already removed from view tree, his parent is parentRelativeLayout
The getParent() is usefully? - not much explanation how to use it, thanks.
In case you have stored your views you can use getParent() to check if view is a direct child for other view. After removing view its parent field will be cleared. For example:
ViewGroup parent = ...;
View child = ...;
assert(child.getParent() == parent); // <-- true
parent.removeView(child);
assert(child.getParent() == parent); // <-- false
Not really sure if I understand your question correctly, but:
when you add the relative layout, be sure to first give it an id (either in your layout.xml file, or from code)
to check existence of the relative layout within the ViewGroup, use ViewGroup's findViewById() method (inherited from View) and pass it the id you've given to the relative layout
if it returns null, the relative layout is not there, otherwise findViewById() will find it
So in short, findViewById() is not only defined for an Activity, but you can call this on any view you would like to use as a starting point for your search.

How to test if a view is in the top layer?

I have a View, I want to know if there is a way to test if the view is in the top layer or it has the biggest z-value.
There's no such property/value like z-index in android except the order in which you add your views in a FrameLayout. However, you may do the following to verify if the view itself is the parent or not:
if(v.getParent() == null){
//view is parent
}
else{
//view is not parent
}

setting z order of View with bringChildToFront()

I'm trying to set the z order of a UI element (i.e. a View) so that it will overlap another element, but calling ViewGroup.bringChildToFront() has a weird side effect....it moves the element to be the last item in the parent (the ViewGroup). Is this a bug, expected behavior, or what? More importantly, how can I set the z order or a View without this unfortunate side effect?
This is the expected behavior. bringChildToFront() just changes the index of the View inside its parent.
To send a view all the way back, do this:
private void moveToBack(View currentView) {
ViewGroup viewGroup = ((ViewGroup) currentView.getParent());
int index = viewGroup.indexOfChild(currentView);
for(int i = 0; i<index; i++) {
viewGroup.bringChildToFront(viewGroup.getChildAt(i));
}
}
bringChildToFront(child) does nothing but changes the index value of the child.
In order to bring a child to the front without using showNext() or showprevious(),
use
setDisplayedChild() and indexOfChild() together.
example
vf.setDisplayedChild(vf.indexOfChild(child));
where child is the view that needs to be brought front.
Thanks

Categories

Resources