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
Register to Be Default App for Custom File Type
How to Rename a File on Sdcard with Android Application
How to Correctly Start Activity from Postexecute in Android
Installation Error: Install_Failed_Older_Sdk
How to Completely Kill/Remove/Delete/Stop an Asynctask
How to Merge Dex - Android Studio 3.0
Retrofit2.0 Gets Malformedjsonexception While the JSON Seems Correct
Android: How to Tell If the Soft Keyboard Is Showing or Not
How to Add Shadow to the Fab Provided with the Android Support Design Library
Notifications Fail to Display in Android Oreo (API 26)
Android Viewpager Setcurrentitem Not Working After Onresume
Play an Audio Clip Onto an Ongoing Call
Android Unknown Command 'Crunch'
Display Data After Every 10 Seconds in Android
How to Programmatically Launch a Specific Application