【问题标题】:CardView shadow not rendered when converted to bitmap转换为位图时不渲染 CardView 阴影
【发布时间】:2015-10-04 08:44:50
【问题描述】:

问题

我正在尝试将一个视图组(它有一个CardView 作为它的子元素之一)保存为 PNG 文件。为此,

  1. 我膨胀视图组并使用所需信息填充视图
  2. 通过Glide将图像加载到图像视图
  3. ViewTreeObserver.OnGlobalLayoutListener 添加到图像视图的ViewTreeObserver 并将要共享的整个(父)视图传递给将视图转换为位图的方法when 图像视图的底部大于零(图像视图的高度属性设置为wrap_content,因此在加载图像之前其底部将为零)。

通过这样做,我可以将视图转换为位图,但是需要注意一点:CardView 的节目不会呈现在位图上。

失败的尝试

到目前为止我已经尝试过:

  1. layerType 属性从“软件”到“硬件”之间切换。
  2. 设置cardUseCompatPaddingCardView 属性的开启和关闭。
  3. 尝试在不使用 Glide 的情况下设置可绘制图像。
  4. 尝试完全不加载可绘制的图像。

代码

这里有代码 sn-ps 可以帮助你们识别问题:

将视图转换为位图的方法

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;
}

正在膨胀并传递给上述getBitmapFromView() 的视图的XML 布局文件。

<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>

【问题讨论】:

  • 不确定是否相关,但也许您可以尝试为卡片视图设置一个小的android:paddingandroid:clipToPadding="false"
  • 很确定它与父视图或卡片视图的填充无关。阴影在屏幕上渲染没有任何问题,并且有足够的空间来确保这一点。不过还是谢谢。
  • 我也面临同样的问题,但我更感兴趣的是把圆角绘制到我的画布上。既没有圆角,也没有绘制阴影。我也使用 view.draw(canvas)
  • 这里也一样。关于这个问题的任何更新?
  • @galex 不,没有:(

标签: android android-layout bitmap shadow android-cardview


【解决方案1】:

只需将cardview改为view,然后设置

android:background="@android:drawable/dialog_holo_light_frame"

因为你需要自己处理填充

【讨论】:

  • 虽然这不是最佳的,但在我的情况下效果很好!
【解决方案2】:

正如@galex 所说 - 仅通过调用 measure 和 layout 才能在视图上绘制阴影。

所以我们不能使用海拔高度。我们也不能使用可绘制阴影,因为那样我们会得到锐角和直边。

解决方案:使用 png 9-path resizable drawable。为此,我们可以使用这个漂亮的工具:Android shadow generator

  1. 为所有 mdpi、hdpi、xhdpi、xxhdpi 和 xxxhdpi 创建 9 路径文件。
  2. 将所有 png`s 放到 res/drawables 文件夹中。
  3. 现在我们可以将这种可绘制的背景用于我们想要看到阴影的视图。

请注意,对于不同的密度,您必须更改以下参数:视图的高度和宽度、阴影偏移(x 和 y)、模糊、圆角半径和填充。

不同密度的乘数:

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

例如如果您需要创建 30dp x 100dp 且半径 = 8dp 的矩形

9.path 你应该生成的图片列表:

  1. 30х100px,弧度 = 8
  2. 45х150px,弧度 = 12
  3. 60х200px,弧度 = 16
  4. 90х300px,弧度 = 24
  5. 120х400px,弧度 = 32

【讨论】:

    【解决方案3】:

    我也有同样的问题。所以在搜索之后,我创建了这个。希望这有帮助 https://medium.com/@ArmanSo/take-control-of-views-shadow-android-c6b35ba573e9

    【讨论】:

    猜你喜欢
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多