CrandellWS
CrandellWS

Reputation: 2804

How can I getHeight of View before removing that View during OnCreate?

So it is not really desired to do this during oncreate though it is my thought that the animations I want to use will work much better with an image rather than a FrameLayout.

So What I have figured so far is (by reading https://stackoverflow.com/a/4406090/1815624), using ViewTreeObserver I am able to use getHeight in the function shown at the bottom which is where the error occurs where it states view.getWidth(), view.getHeight()

Really I just want to get that image of the view and nuke the original with something like removePieChart(fl); Though as soon I used removePieChart(fl); the errors happen...

A timed event may work but it seems like a bad idea...Any suggestions?

Please and Thanks

    protected void onCreate(Bundle savedInstanceState) {
        final FrameLayout tv = (FrameLayout)findViewById(R.id.pieChart);
        final ViewTreeObserver observer= tv.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                View fl = findViewById(R.id.pieChart);
                image.setImageBitmap(viewToBitmap(fl));
                removePieChart(fl);
//                observer.removeOnGlobalLayoutListener(this);
            }
        });
    }
    private void removePieChart(View fl) {
        ((ViewManager)fl.getParent()).removeView(fl);
    }

and for reference here is the viewToBitmap method from https://stackoverflow.com/a/21726101/1815624

public Bitmap viewToBitmap(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    try {
        FileOutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory() + "/file.png");
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
        output.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bitmap;
}

Upvotes: 0

Views: 191

Answers (3)

Kushal
Kushal

Reputation: 805

   **Try this code**

    final LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
    final ViewTreeObserver observer= layout.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
    {
            @Override
            public void onGlobalLayout()
            {
                    Log.d("Log", "Height: " + layout.getHeight());
            }
    });

Upvotes: 2

EpicPandaForce
EpicPandaForce

Reputation: 81539

I recommend using the following class I snatched a while ago from the since-deleted Flow-Sample made by Square:

import android.view.View;
import android.view.ViewTreeObserver;

public final class ViewUtils {
    public interface OnMeasuredCallback {
        void onMeasured(View view, int width, int height);
    }

    public static void waitForMeasure(final View view, final OnMeasuredCallback callback) {
        int width = view.getWidth();
        int height = view.getHeight();

        if (width > 0 && height > 0) {
            callback.onMeasured(view, width, height);
            return;
        }

        view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override public boolean onPreDraw() {
                final ViewTreeObserver observer = view.getViewTreeObserver();
                if (observer.isAlive()) {
                    observer.removeOnPreDrawListener(this);
                }

                callback.onMeasured(view, view.getWidth(), view.getHeight());

                return true;
            }
        });
    }

    private ViewUtils() {
    }
}

Then you use it as

ViewUtils.waitForMeasure(view, new ViewUtils.OnMeasuredCallback() {
    public void onMeasured(View view, int width, int height) {
        Log.d(TAG, "Do something with height [" + height + "]");
    }
});

Upvotes: 2

CrandellWS
CrandellWS

Reputation: 2804

Firstly got to remove the listener addOnGlobalLayoutListener so it stop it from repeatedly calling the removePieChart() method. Once that is done, you can then remove the view.

So onGlobalLayout get's changed :

        public void onGlobalLayout() {

            View fl = findViewById(R.id.pieChart);
            image.setImageBitmap(viewToBitmap(fl));
            removePieChart(this); //TODO remove the PieChart resource
        }

and also removePieChart() is changed

private void removePieChart(ViewTreeObserver.OnGlobalLayoutListener a) {

    final FrameLayout fl = (FrameLayout)findViewById(R.id.pieChart);
    final ViewTreeObserver observer= fl.getViewTreeObserver();
     observer.removeOnGlobalLayoutListener(a);
    ((ViewManager)fl.getParent()).removeView(fl);
}

Upvotes: 1

Related Questions