Call to 'Getdrawingcache' Returns Null When Scroll Is Enabled

Call to `getDrawingCache` returns null when scroll is enabled

I solved it. Created a bitmap of view size and drew the view into it.

TableLayout page = (TableLayout) findViewById(R.id.page);
Bitmap pageBmp = Bitmap.createBitmap(page.getWidth(), page.getHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(pageBmp);
page.draw(canvas);

Used the pageBmp bitmap..

view.getDrawingCache() returns null only in Samsung Galaxy note 8.0?

As per your explanation, it seems like large images are not draw by the code, so for that please use below code it it is work,

I have not tested yet but I think this will help you

   public static Bitmap loadLargeBitmapFromView(View v) 
{
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);

Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}

Edit your method as below

     public Bitmap getResizedBitmap(int originial_width, int original_height) {
this.setDrawingCacheEnabled(true);
Bitmap bitmap = null;
if(this.getDrawingCache()==null)
{
bitmap = loadLargeBitmapFromView(this);
}
else
{
bitmap = Bitmap.createBitmap(this.getDrawingCache());
}

return Bitmap.createScaledBitmap(bitmap,originial_width_answersheet,original_height_answersheet,false);
}

Android View.getDrawingCache returns null, only null

I was having this problem also and found this answer:

v.setDrawingCacheEnabled(true);

// this is the important code :)
// Without it the view will have a dimension of 0,0 and the bitmap will be null
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache

Bitmap from TextView (getDrawingCache) always null

Do this before getting drawing cache it will solve the problem

view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

and then getDrawingCache() will return a bitmap and draw that bitmap on your canvas.

and if you are using bitmaps in your app prefer to clear them from memory by calling recycle() method on them so that bitmap get cleared from the memory for your safe side to avoid outOfMemoryException

getDrawingCache always returns the same Bitmap

I think that's because your old Bitmap is still in your drawing cache. Because of this, you first need to delete it from the cache and then put the new Image in the cache. Take a look at this question, which seems to be on the same topic:

Deletion of drawing cache

EDIT:
So, here is the code which is working for me. I use a Button to save the Bitmap and then set the Bitmap to an Image View:

private View rootView;
private ImageView bitmapView;
private Button switchButton;
public Bitmap capturedScreen;
public boolean bitmapNeeded = false;

...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// do the other stuff
rootView.setDrawingCacheEnabled(true); //enable Drawing cache on your view
switchButton.setOnClickListener(this);
}

...

@Override
public void onClick(View v) {
if (v == switchButton) { //when the button is clicked
captureScreen();
}
}

public void captureScreen() {
rootView.buildDrawingCache();
capturedScreen = Bitmap.createBitmap(rootView.getDrawingCache());
imageView.setImageBitmap(capturedScreen);
rootView.destroyDrawingCache();
}

....

//In the onDraw method of your View:
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(capturedScreen, 0, 0, paint);
}

This is how it works:
Everytime the user clicks the button, everything inside rootView is saved as a bitmap and then drawn to the imageView.
You can of course call the captureScreen Method from anywhere in your code, if you need to to.

I hope this example helps you.

view.getDrawingCache() is deprecated in Android API 28

I have found a way to use PixelCopy API for retrieving the view as a Bitmap. Used Kotlin

fun getBitmapFromView(view: View, activity: Activity, callback: (Bitmap) -> Unit) {
activity.window?.let { window ->
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val locationOfViewInWindow = IntArray(2)
view.getLocationInWindow(locationOfViewInWindow)
try {
PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult ->
if (copyResult == PixelCopy.SUCCESS) {
callback(bitmap)
}
// possible to handle other result codes ...
}, Handler())
} catch (e: IllegalArgumentException) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
e.printStackTrace()
}
}
}

Android drawing cache

There's a hard limit on drawing cache size, available via the ViewConfiguration class.. My view is larger than allowed for caching.

FYI, the sources of the View class are available via the SDK Manager for some (not all) Android versions.

Is there a maximum bitmap size when using getDrawingCache?

You can drop the buildDrawingCache method and just use canvas. Since you are building the view programmatically you also need to call measure() and layout() before you can get a bitmap.

The key lines are:

    tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
tvText.draw(canvas);

Here is the full example:

private Bitmap getBitmap(Context context){

final int NUMBER_OF_LINES = 153;
final int width = 600;
final int fontSize = 24;

// create string with NUMBER_OF_LINES
StringBuilder testString = new StringBuilder();
for (int i = 0; i < NUMBER_OF_LINES; i++) {
testString.append("\n");
}

// Create TextView
TextView tvText = new TextView(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
tvText.setTextSize(fontSize);
tvText.setWidth(width);
tvText.setLayoutParams(params);
tvText.setBackgroundColor(Color.WHITE); // even setting the background color affects crashing or not
tvText.setText(testString);
tvText.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
tvText.layout(0, 0, tvText.getMeasuredWidth(), tvText.getMeasuredHeight());

// Create the bitmap from the view
Bitmap bitmap = Bitmap.createBitmap(tvText.getWidth(), tvText.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
tvText.draw(canvas);

return bitmap;
}


Related Topics



Leave a reply



Submit