2

Please help me understand why getDrawingCache() is returning null when called on my image button view (appcompatimagebutton) from within my ontouchlistner attached to my image button view.

Mainly, in trying to solve this, I have been referring to this question:

Android View.getDrawingCache returns null, only null

which has not solved my problem. I am sure I am overlooking something or not fully understanding something. Please help me figure out what it is.

Notes:

1) it seems to make no difference weather i use ImageButton or AppCompatImageButton (but i am using appcompat because in the actual project I need features it offers that ImageButton does not).

2) I do not see why i should need to call the view's measure and layout methods since the layout is already painted to the screen by the time a user would fire ontouch() but thought i'd include it anyway as many answers i found about seemed to indicate this was required.. it doesn't work if i take them out either.

3) it does not appear to matter if I place the setEnableDrawingCache and buildDrawingCache calls in the onTouch or in the onCreate with the AppCompatImageButton view initialization. In either case, my ontouchlistener call to the image button view's getDrawingCache returns null.


here is the code sample,

Thanks!

public class MainActivity extends AppCompatActivity {
    AppCompatImageButton mImageButton;
    Bitmap mBitmapDrawingCache;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //create image button
        mImageButton = new AppCompatImageButton(this);
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(270, 270);
        mImageButton.setLayoutParams(layoutParams);

        //getDrawingCache() in ontouchlistener returns null regardless if this is set
        int mseWidth = View.MeasureSpec.makeMeasureSpec(270, View.MeasureSpec.EXACTLY);
        int mseHeight = View.MeasureSpec.makeMeasureSpec(270, View.MeasureSpec.EXACTLY);
        mImageButton.measure(mseWidth, mseHeight);
        mImageButton.layout(0, 0, 270, 270);
        /* this does not work either
        int mseWidth = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int mseHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        mImageButton.measure(mseWidth, mseHeight);
        mImageButton.layout(0, 0, mImageButton.getMeasuredWidth(), mImageButton.getMeasuredHeight());
        */

        //getDrawingCache() in ontouchlistner returns null regardless if either, both or none of these are set
        //mImageButton.buildDrawingCache();
        mImageButton.setDrawingCacheEnabled(true);

        //attach image button view to content view
        ((FrameLayout) findViewById(android.R.id.content)).addView(mImageButton);

        //set touch listener
        mImageButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                //why is this line returning null instead of a Bitmap ?
                mBitmapDrawingCache = Bitmap.createBitmap(v.getDrawingCache());

                Log.d("TAG_A", mBitmapDrawingCache.toString());

                return false;
            }
        });
    }
}
Community
  • 1
  • 1
dl77sea
  • 21
  • 2

1 Answers1

0

In order to get bitmap out from your View, the order in which you generate cache is something like this:

mImageButton.setDrawingCacheEnabled(true);
mImageButton.buildDrawingCache();
mBitmapDrawingCache = Bitmap.createBitmap(mImageButton.getDrawingCache());

You need to call this all together inside OnTouchListener or more preferably OnClickListener (if you want to generate bitmap only when clicked).

However, I'm not sure why you are calling all the MeasureSpec stuff... If you are loading the image through setContentView(R.layout.activity_main); then don't be bothered with all manual measuring.

waqaslam
  • 67,549
  • 16
  • 165
  • 178
  • Thanks for your response, Placing those calls in onClick is not preferable for my design. Placing those calls in onTouch does not work for me when i test it. If this is working for other people when they test it, i wonder if there is not something peculiar about my hardware that i am testing it on? is it possible that this will work on some devices and not others? – dl77sea Aug 08 '16 at 13:27