Tedd,
  I'm quite sure that you don't want to do any of this in onDraw.

  It's just a thought, but suppose that measureHeight, in addition to
remembering the width it had just returned, kept a number that
represented the error in that width.  When it returns, it requests a
re-layout, unless that error is small.  That would allow you to avoid
the second thread altogether... a thread that is, surely, going to be
hard to manage over your Activitiy's lifecycle.

-blake
Programming Android, FTW!
http://oreilly.com/catalog/0636920010364


On Sep 9, 1:48 pm, Ted Hopp <ted.h...@gmail.com> wrote:
> I asked this question on 
> SO<http://stackoverflow.com/questions/7015097/best-practices-for-dealing...>a 
> month ago but got no answer. Maybe I'll have better luck here. :)
>
> I keep running into a sizing and layout problem for custom views and I'm
> wondering if anyone can suggest a "best practices" approach. The problem is
> as follows. Imagine a custom view where the height required for the content
> depends on the width of the view (similar to a multi-line TextView).
> (Obviously, this only applies if the height isn't fixed by the layout
> parameters.) The catch is that for a given width, it's rather expensive to
> compute the content height in these custom views. In particular, it's too
> expensive to be computed on the UI thread, so at some point a worker thread
> needs to be fired up to compute the layout and when it is finished, the UI
> needs to be updated.
>
> The question is, how should this be designed? I've thought of several
> strategies. They all assume that whenever the height is calculated, the
> corresponding width is recorded.
>
> The first strategy is shown in this code:
>
> protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
>    int width = measureWidth(widthMeasureSpec);
>    setMeasuredDimension(width, measureHeight(heightMeasureSpec, width));
>
> }
>
> private int measureWidth(int widthMeasureSpec) {
>    // irrelevant to this problem
>
> }
>
> private int measureHeight(int heightMeasureSpec, int width) {
>    int result;
>    int specMode = MeasureSpec.getMode(measureSpec);
>    int specSize = MeasureSpec.getSize(measureSpec);
>    if (specMode == MeasureSpec.EXACTLY) {
>        result = specSize;
>    } else {
>        if (width != mLastWidth) {
>            interruptAnyExistingLayoutThread();
>            mLastWidth = width;
>            mLayoutHeight = DEFAULT_HEIGHT;
>            startNewLayoutThread();
>        }
>        result = mLayoutHeight;
>        if (specMode == MeasureSpec.AT_MOST && result > specSize) {
>            result = specSize;
>        }
>    }
>    return result;
>
> }
>
> When the layout thread finishes, it posts a Runnable to the UI thread to set
> mLayoutHeight to the calculated height and then call requestLayout() (and
> invalidate()).
>
> A second strategy is to have onMeasure always use the then-current value for
> mLayoutHeight (without firing up a layout thread). Testing for changes in
> width and firing up a layout thread would be done by overriding
> onSizeChanged.
>
> A third strategy is to be lazy and wait to fire up the layout thread (if
> necessary) in onDraw.
>
> I would like to minimize the number of times a layout thread is launched
> and/or killed, while also calculating the required height as soon as
> possible. It would probably be good to minimize the number of calls to
> requestLayout() as well.
>
> From the docs, it's clear that onMeasure might be called several times
> during the course of a single layout. It's less clear (but seems likely)
> that onSizeChanged might also be called several times. So I'm thinking that
> putting the logic in onDraw might be the better strategy. But that seems
> contrary to the spirit of custom view sizing, so I have an admittedly
> irrational bias against it.
>
> Other people must have faced this same problem. Are there approaches I've
> missed? Is there a best approach?

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to