THE PROBLEM
I'm try to save a view group (which has a CardView
as one of its childern) as a PNG file. To achieve this,
ViewTreeObserver.OnGlobalLayoutListener
to the ViewTreeObserver
of the image view and pass the entire (parent) view that is going to be shared to a method that converts the view to a bitmap when image view's bottom is greater than zero (image view's height attribute is set to wrap_content
, thus its bottom will be zero until image is loaded).By doing this, I'm able to convert the view to a bitmap, however, with one caveat: the CardView
's show is not rendered on the bitmap.
FAILED ATTEMPTS
So far I've tried:
layerType
attribute from "software" to "hardware".cardUseCompatPadding
attribute of the CardView
.THE CODE
Here are code snippets that might help you guys identify the problem:
The method used to convert a view to a bitmap
public static Bitmap getBitmapFromView(View view) {
//Define a bitmap with the same size as the view
Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(b);
//Get the view's background
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
else
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return b;
}
XML layout file of the view that's being inflated and passed to the getBitmapFromView()
above.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="16dp">
<com.devspark.robototextview.widget.RobotoTextView
android:id="@+id/title"
style="@style/text_subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginBottom="@dimen/lessons_horizontal_margin_narrow"
android:layout_marginLeft="@dimen/lessons_horizontal_margin_narrow"
android:layout_marginRight="@dimen/lessons_horizontal_margin_narrow"
android:layout_marginTop="@dimen/lessons_horizontal_margin_narrow"
android:gravity="left"
app:typeface="roboto_medium" />
<com.devspark.robototextview.widget.RobotoTextView
android:id="@+id/text"
style="@style/text_subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/lessons_horizontal_margin_narrow"
android:layout_marginRight="@dimen/lessons_horizontal_margin_narrow"
android:gravity="left"
android:textColor="@color/text"
app:typeface="roboto_regular" />
<android.support.v7.widget.CardView
android:id="@+id/image_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/lessons_horizontal_margin_narrow"
app:cardCornerRadius="@dimen/lessons_image_card_corner_radius"
app:cardElevation="3dp"
app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@null"
app:riv_corner_radius_top_left="@dimen/lessons_image_card_corner_radius"
app:riv_corner_radius_top_right="@dimen/lessons_image_card_corner_radius" />
<com.devspark.robototextview.widget.RobotoTextView
android:id="@+id/caption"
style="@style/text_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/lessons_image_card_caption_margin"
android:gravity="left"
app:typeface="roboto_condensed_regular" />
</LinearLayout>
</android.support.v7.widget.CardView>
<!-- Some other views that aren't particularly interesting -->
</LinearLayout>
just change cardview to view, and set
android:background="@android:drawable/dialog_holo_light_frame"
ofcause you need to deal the padding yourself
As @galex said - shadows are not drawn on views only by calling measure and layout.
So we can't use the elevation. Also we can't use the drawable shadow, because then we get sharp angles and straight sides.
Solution: use the png 9-path resizable drawable. For this we can use this beautiful tool: Android shadow generator
Note that for different densities, you must change following parameter: height and width of the view, shadow offsets (x and y), blur, round corners radius and paddings.
Multipliers for diffrent densities:
LDPI - x0.75//practically not used, so you can do without it
MDPI - x1.0// means original size
HDPI - x1.5
XHDPI - x2.0
XXHDPI - x3.0
XXXHDPI - x4.0
For example if you need to create rectangle with 30dp x 100dp and radius = 8dp
list of 9.path images you should generate:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With