Issue
I'm implementing a custom ImageView that have to load a Bitmap from disk. The Bitmap should be scaled exactly so, that its width must be equal to the final width a parent layout has been allocated to my ImageView and height is calculated to keep an aspect ratio.
So, the question is what is the proper place during the View life cycle to put heavy operations that depend on View's dimensions known after the layout is done?
(I'd like to keep it simple and not use threads, however.)
- Most likely it's a bad idea to put that code in
onDraw()method, since it should be as efficient as possible. From the other hand, myImageViewis unlikely to be resized, so it would kill only the firstonDraw()'s performance and it wouldn't affect any subsequent calls toonDraw(). So I'm not sure about this option. - I could put it at the end of
onLayout(boolean changed, int l, int t, int r, int b)executing my heavy codeif (changed == true). Is this a good idea? - The 3rd option I see is to do it in the
onSizeChanged()callback. My only concern here is whether this callback is guaranteed to be called only once per actual view's size change. I'm inclined to use this option, since in my tests it works fine.
Could someone give an insight on this?
Solution
Both the option 2 and 3 works for you to get the View's correct dimensions.
onDraw() is called only after onLayout(). You can get the dimensions in the onLayout() itself and it is better to avoid doing any unnecessary works inside onDraw(). So I would choose either option 2 or option 3.
And also be aware that onSizeChanged() is sometimes called with zero. Ian in this thread:
Be aware too that onSizeChanged() is sometimes called with parameters of zero -- check for this case, and return immediately (so you don't get a divide by zero when calculating your layout, etc.). Some time later it will be called with the real values.
Another option is to add a runnable to the View's queue, using View.post()
Quote and example from this thread:
The UI event queue will process events in order. After setContentView() is invoked, the event queue will contain a message asking for a relayout, so anything you post to the queue will happen after the layout pass
final View view=//smth;
...
view.post(new Runnable() {
@Override
public void run() {
view.getHeight(); //height is ready
}
});
Using this method, we can be sure that our code is executed only once.
Answered By - Bob
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.