What is the difference between removing a view from it's parent and setting it's visibility as GONE?
If you remove a view from the parent, its no longer in its list of children. You can then add it to any other ViewGroup. If you loop through the old paren't children it won't come up, and it won't be called when the ViewGroup does things like resize itself.
If you make it GONE, its still a child of the ViewGroup. It can't be added to another, because it can have only 1 parent. It will still be called for things like resizing of the view group.
If you set a View's visibility GONE, it will look like it doesn't exist anymore, but it actually exists inside its parent, it is there, you can still manipulate it at your will, however, if you remove that view from its parent it will be actually out of it with all the consequences.
For instance: If you remove a view from a LinearLayout, it won't be inside of that linearLayout, and therefore it won't be affected by its parent gravity, but if you just set your view visibility GONE, it'll be still affected by its parent gravity, even if you can't see it because your view is invisible.
I'm sorry if it sounds a little bit unclear, but it is kind of hard to explain for me.
Related
I have a created a mapview with markers on it.
Looking at this picture below:
Grandparent is a filling View
Parent is my MarkerView
Child is a marker which is clickable
Parent has clipChildren(false) and thus the children are visible.
My problem is that the children are clickable, except for the part where Child 2 is outside the Parent.
Parent also has the appropriate TouchDelegate (and I also tried this for the children).
How can I make the complete child clickable?
I couldn't make it work without changing the elements.
I ended up enlarging the parent and using setTranslationY for the markers to keep them in place like this:
I had a similar issue and fixed it by setting app:elevation="XXdp" to the child.
The reason why you can't do this is that the default implementation of ViewGroup#dispatchTouchEvent(MotionEvent ev) iterates over the children (not the grandchildren) to look for a child that are a target (is on bottom of the click event point) and can receive touch events. It will find nothing if you touched the part that it is outside the bounds of Parent, which is the only child of Grandparent. If it does not find Parent, Parent will never be able to make a look up on its children (Children 1 and Children 2) and eventually dispatch the event to Child 2.
So you either increase the size of Parent (as the acceptable answer), which is the most easy way, or you will have to override the method ViewGroup#dispatchTouchEvent(MotionEvent ev) of your Grandparent to make a more complex lookup, like looking up grandchildren too. The method is already fairly complex, if anyone finds a implementation, please share because I don't have one.
I am trying to draw a View in a ViewGroup without adding it to the child list.
I am doing this because I want to display something like a ProgressBar in the exact center of layouts like a LinearLayout so I don't want the layout to handle the measuring and layouting.
I also don't want to complicate the view hierarchy by adding extra layouts just to achieve this effect so my solution was to extend the LinearLayout, create a ProgressBar and handle measuring, layouting and drawing for that view myself.
My implementation seems to work ok from what I tested but I am wondering if there is anything I am not noticing or if there are any problems that can appear in the future.
From what I understand calling addView also sets the child view's parent and calls dispatchAttachedToWindow, these methods are package-private so I can't call them myself.
Is there any side effect that can arise from calling measure, layout and draw on a view that has no parent and that was not "attached" to a window? Is there a safer way to achieve the same effect?
Thanks.
I could not find anything that straight out answers this question. If I set the component (such as a Button, ListView, EditText) in the xml with a visibility of GONE, am I still able to interact with those components even though they are invisible? I tested it out with a Button and it seems to be no but I want to make sure.
When the visibility is set to GONE, the component is removed from the view hierarchy and no space is set aside for it. Moreover, there is no way for the user to interact with it (However, changes made to the View by the programmer while it is GONE become manifest when the visibility is changed to VISIBLE).
When the visibility is set to INVISIBLE, the component is still actually present in the view hierarchy, and space is calculated for it.
Let me explain the scenario that I want to achieve:-
Consider the below as the Layout I have inside a Parent_Linearlayout:
[Linear Layout] (Fill_Parent, Wrap_Content)
[ScrollView]
Activity's setContentView is set to the Parent_Linearlayout
In the application, when a condition is met, I want the Scrollview to be removed from the screen and instead put another View in its place.
I've been able to do this, & when I remove the ScrollView, I'm applying translate Animation to it so that it seems as if the View has gone to the top -before removing it.
But when the animation occurs, the ScrollView translates OVER the Linear layout present above it.
How do I restrict it, so that the scrollview does not go over the linear layout, but disappears at the base of the Linearlayout. I want the linearlayout to always stay visible..
I've been trying to do this from quite some time, but I've not been able to get desired results..
Could someone kindly help me out here??
I don't quite understand your description of your layout, but the Android view system is drawn based on the ordering of the views in the hierarchy. Views added later to a parent are drawn after those added earlier. So if you always want the LinearLayout to be drawn on top of the ScrollView if/when they overlap, then declare or add the ScrollView object to its parent before the LinearLayout object.
In thinking more about this, I suppose the ordering here is important because you want the ScrollView to be placed below the LinearLayout in the parent of both of these views. Putting the ScrollView first (and thus having it painted first) would then put it above the other LinearLayout, which isn't what you want.
There are various ways to achieve what you want. For example, you could use a RelativeLayout as the parent of the views, then the ordering is not important.
Alternatively, you could place the ScrollView inside another LinearLayout (and that LinearLayout would be the second child of the overall parent layout). Then when you animate the ScrollView, it would be clipped by its immediate parent, which I believe would give you the effect you're looking for (make sure that setClipChildren() is set to true on this new intermediate LinearLayout, which it is by default, otherwise it won't clip the ScrollView as it animates out of it). Note that this approach would necessitate different animation values, since you are now animating the view outside of its parent (the new LinearLayout).
I have a ViewGroup and I'm adding child Views to it like this:
mViewGroup.addView(view, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
(the WRAP_CONTENT is important for the onclicklistener to work as expected).
So far so good, but later I move the child Views around dynamically by either overriding their onDraw methods or by overriding the ViewGroups:
protected boolean getChildStaticTransformation(View child, Transformation t)
The problem is that the Children disappear if they are moved outside their original region which seems to be calculated when they are first added. I tried calling setClipChildren(false); but it didn't work.
I could solve the problem by using LayoutParams.FILL_PARENT when adding the child views but in this case the onClickListener would react to any click on the whole ViewGroup and I want it to only react to clicks on the specific area where my transformed child View is located.
Maybe I could still use LayoutParams.FILL_PARENT if there is a way to define where the clickable region for the View should be.
Any suggestions?
Perhaps you should experiment with margins and paddings of your child views. Otherwise you could try to use a different ViewGroup layout like a FrameLayout where the postion of each view can be set by its margins.