We know ViewTreeObserver is used to register listeners that can be notified of global changes in the view tree. There are two method defined in this class are
addOnGlobalLayoutListener(ViewTreeObserver.OnGlobalLayoutListener listener) and addOnPreDrawListener(ViewTreeObserver.OnPreDrawListener listener). But the the purpose of these methods are not clearly understandable to me which described in the developer site. I tried to understand it and also searched in google but was unable to find clear picture about this topic. Any help is greatly handful for me.
OnPreDrawListener
Gets called just before onDraw() method gets invoked. At this point, all views in the tree have been measured and given a frame. Therefore you can properly manipulate view in this callback
OnGlobalLayoutListener
This listener gets called:
- when visibility state changes. In example when view has been drawn it becomes visible and this gets called.
- when you addView state of view tree changes
Related
I'm not sure about the usage of onAttachedToWindow.
My question is basically about the documentation.
Which mentions:
[...] it may be called any time before the first onDraw --
including before or after onMeasure(int, int)
I what to know:
when it is called before onMeasure and when is it called after.
The Story behind:
I am adding OnGlobalLayoutListener in onAttachedToWindow and remove it in onDetachedFromWindow. Because is somehow logic to me to handle the layouting when the view is added to the window.
But I am concerned that the first onGlobalLayout calls get lost, if the Listener is not added yet. (because onMeasure usually happens during the layouting)
If someone got a better approach for my problem, feel free to give me a hint.
Docs are correct, and you should not rely on onWindowAttach/Detach being in sync with onMeasure or onLayout pass.
If your View class is interested in parent hierarchy changes, I'd advice against such a design. The Parent UI should notify sub-views of hierarchy changes. So, OnGlobalLayoutListener better be used by an enclosing UI class.
Also, View class has onSizeChanged() that you can override to detect when it has been measured up.
According to concept of recycling items mechanism in ListView.
I want to know, actually, how i can detect a moment when a View going off-screen.
I explain why.
In most cases ListView have a custom
Adapter(? extends ArrayAdapter / ? extends BaseAdapter, etc.).
getView(...) method allows to manipulate visibility and content of views (text,bitmaps,drawables,etc.)
And in some cases i need to launch a separate Thread which doing background work, and after that update UI. Actually - using AsyncTask.
When i have many items in ListView each call of getView will be produced start a new Thread. I need to cancel them if View is no more longer present on the screen. How to do this?
You can override onDetachedFromWindow for the view.This will let you know when the view is going off-screen.The docs says:
protected void onDetachedFromWindow ()
Added in API level 1 This is called when the view is detached from a
window. At this point it no longer has a surface for drawing.
See Also
onAttachedToWindow()
is there a listener or some way to determine when contentView is created? I have used other type listeners and they work for other child views inside of content view. however content view is different. I have not yet found anything that works.
Have you tried onContentChanged() yet?
The documentation says
This hook is called whenever the content view of the screen changes (due to a call to Window.setContentView or Window.addContentView).
I am populating a linear layout dynamically. Depending upon response, I have to clear the past child views and create new views. I have read the document, but still be confused with the couple methods, they all look the same function. Which function I should use.
As Scott Biggs points out, the difference is not a big one. The only difference is that removeAllViews() calls requestLayout() and invalidate() afterwards. The key to why this difference is here is to understand the naming of removeAllViewInLayout(). Confusingly, its meaning isn't "remove all views within this view layout."
If we look at the similar method, removeViewInLayout(), we can understand what it's supposed to mean:
Removes a view during layout. This is useful if in your onLayout() method, you need to remove more views.
So removeAllViewsInLayout() actually means "remove all views, and we're calling this method during a layout pass (i.e. onLayout())". That's why removeAllViewsInLayout() doesn't call through to requestLayout(), as it's assumed that you're already currently inside a layout pass, so requesting another layout pass is unneeded.
If you use removeAllViewsInLayout(), then it's your responsibility to ensure that you're calling this during a layout pass, or to properly call requestLayout() and invalidate() as needed.
removeAllViews() : Call this method to remove all child views from the ViewGroup.
removeAllViewsInLayout() : Called by a ViewGroup subclass to remove child views from itself, when it must first know its size on screen before it can calculate how many child views it will render.
Well, looking at the source, there isn't much difference:
public void removeAllViews() {
removeAllViewsInLayout(); // Details implemented here
requestLayout();
invalidate(true);
}
So unless you want to call invalidate() at a time of your choosing, you might as well use removeAllViews() and save yourself a bit of typing.
EDIT
For a more detailed explanation, see David Lui's answer. To sum it up, use removeAllViews() unless you're in the process of constructing a View--in which case you'd call removeAllViewsInLayout().
I wanted to know whether the onDraw method get called without the programmers knowledge. I know that it is called at the first time View is loading and I know it calls when I call invaliade(). But does it calls in any other times?
Yes, whenever a parent view is redrawing itself like if the custom view is within a ScrollView whenever you scroll it...