【问题标题】:CardView has extra margin in each edge on Pre-LollipopCardView 在 Pre-Lollipop 的每个边缘都有额外的边距
【发布时间】:2015-03-16 01:43:49
【问题描述】:

这是两张照片。

在棒棒糖上:

在棒棒糖前:

我们可以看到它只是靠近 Lollipop 的屏幕一侧。这就是我想要的。但在 Pre-Lollipop 设备上,它在屏幕边缘有额外的边距。你们有什么经验吗?谢谢。

这是布局xml:

<android.support.v7.widget.CardView
        android:id="@+id/card_title_schedule"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_centerVertical="true"
        app:cardCornerRadius="0dp"
        app:cardBackgroundColor="@color/colorAccent"
        >

【问题讨论】:

    标签: android android-5.0-lollipop android-cardview


    【解决方案1】:

    所以在这里它在 Kitkat 上运行得非常好,准确地说是三星设备。

    我尝试了card_view:cardUseCompatPadding="true",但无济于事。没用!

    然后我从 stackoverflow 帖子中发现了这个 card_view:cardPreventCornerOverlap="false" 和瞧!工作!没有圆角(因为卡片有图像背景,所以我不想要)。

    道德是,额外的填充是因为那些需要禁用的小圆角。基本上这不是缺陷,而是设计约束!

    ORIGINAL SOF REPLY

    图像:请注意,顶角是边缘(背景中具有颜色和图像的视图),而底部只有 TextViews 而没有背景,因此是圆角。这意味着如果视图在 CardView 内请求 match_parentcard_view:cardPreventCornerOverlap="false" 将允许在受影响的角落上占用它。

    【讨论】:

    • 通过将其更改为 false,它确实可以在这些支持库中工作。我想可能是google已经默默修复了。
    • 谢谢;这使问题变得不那么明显了。但是,在我的 Sony Xperia M (Android 4.1.2) 上,cardView 周围仍有一两个像素的边距/填充。
    • 这对我有用:android.jlelse.eu/…
    • 但这也违背了 CardView 的两个主要目的之一,一个是您保留的阴影,另一个是圆角,无论里面有哪些视图。不幸的是,我需要圆角和阴影,所以这对我来说无法解决。
    【解决方案2】:

    在 L 之前,CardView 为其内容添加填充并在该区域绘制阴影。这个填充量等于 maxCardElevation + (1 - cos45) *cornerRadius 在边和 maxCardElevation * 1.5 + (1 - cos45) *cornerRadius 在顶部和底部。

    来自 CardView 参考 here

    尝试像这样在CardView 上设置负左边距

    <android.support.v7.widget.CardView
            android:id="@+id/card_title_schedule"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            app:cardCornerRadius="0dp"
            app:cardBackgroundColor="@color/colorAccent" 
            app:cardUseCompatPadding="true"
            android:layout_marginLeft="-2dp" />
    

    您可能需要调整边距以获得所需的结果。

    PS,这是一种 hack-y 方式。

    【讨论】:

    • 感谢您的回答。你说的对。我没有注意到“在该区域绘制阴影”.. 到目前为止,也许黑客方式是唯一的。否则我不应该在这种情况下使用 CardView。
    • 不客气。这是我现在唯一能想到的方法。如果您找到更好的方法在棒棒糖之前的设备上绘制阴影,请告诉我。 编辑: 这是我刚才遇到的问题:github.com/dmytrodanylyk/shadow-layout 我认为它以同样的方式绘制阴影。随意测试一下。
    【解决方案3】:

    我意识到这个问题已经得到解答,但我想补充一点,除了card_view:cardPreventCornerOverlap="false",我还必须设置CardView.setMaxCardElevation(0) 以消除棒棒糖前的边距。仅将高程设置为 0 不起作用。我正在使用支持库 v23.4.0。

    【讨论】:

    • 感谢 "setMaxCardElevation" 指针。在我的情况下,为了摆脱所有边缘的“额外”填充(即使 CardView 或其子项上没有角半径)我必须设置这 3 个(在 xml 中):app:cardMaxElevation="0dp" app:cardElevation="0dp" app:cardPreventCornerOverlap="false"。 .. 使用 com.android.support:cardview-v7:25.2.0
    • 我修正了你的评论。谢谢。
    【解决方案4】:

    试试card_view:cardUseCompatPadding="true"

    如果我们将此属性设置为 true,则边距在所有版本上的效果都相同。

    开发者说明

    在 API v21+ 中添加填充,以使用相同的测量值 以前的版本。

    来源docs

    【讨论】:

      【解决方案5】:

      如果需要 Android 4(棒棒糖前)行为,将 app:cardUseCompatPadding="true" 添加到 CardView 应该可以解决此问题。

      如果需要 Android 5+ 的行为(这实际上是根据材料指南的卡片视图的正确行为),则无法轻松实现完全相同的事情。我通常使用这个修复来避免定义多个布局文件并在所有设备上都有合理的输出:

      <android.support.v7.widget.CardView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          app:contentPaddingRight="@dimen/fix_cardview"
          app:contentPaddingLeft="@dimen/fix_cardview"
          app:contentPaddingTop="@dimen/fix_cardview_vertical"
          app:contentPaddingBottom="@dimen/fix_cardview_vertical" />
      

      在正常的values/dimens.xml 文件中,我们应该有:

      <dimen name="fix_cardview">-8dp</dimen>
      <dimen name="fix_cardview_vertical">-12dp</dimen>
      

      values-v21/dimens.xml:

      <dimen name="fix_cardview">0dp</dimen>
      <dimen name="fix_cardview_vertical">0dp</dimen>
      

      请注意,-8dp-12dp 的数字可能必须针对您的布局进行调整,因为它们取决于海拔等。

      这只是一种避免在 Android 4 视图中出现丑陋填充的变通方法,而无需在不同的布局文件中使用不同的视图(这通常会使代码更难维护)

      【讨论】:

        【解决方案6】:

        为解决 PR​​E-L 版本的“阴影空间”问题,您可以通过负值动态更新 CardView 边距以补偿空间。

        要获得实际的阴影空间:

        shadowSpaceLeft = getPaddingLeft() - getContentPaddingLeft();
        

        固定边距:

        layoutParams.leftMargin -= shadowSpaceLeft;
        

        这适用于所有 Android 版本,因为我们动态获取填充值和 contentPadding 值。

        例如,当我们设置新的布局参数时,这里有一个类:

        public class NoPaddingCardView extends CardView {
        
            public NoPaddingCardView(Context context) {
                super(context);
                init();
            }
        
            public NoPaddingCardView(Context context, AttributeSet attrs) {
                super(context, attrs);
                init();
            }
        
            public NoPaddingCardView(Context context, AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
                init();
            }
        
            private void init() {
                // Optional: Prevent pre-L from adding inner card padding 
                setPreventCornerOverlap(false);
                // Optional: make Lollipop and above add shadow padding to match pre-L padding
                setUseCompatPadding(true);
            }
        
            @Override
            public void setLayoutParams(ViewGroup.LayoutParams params) {
                // FIX shadow padding
                if (params instanceof MarginLayoutParams) {
                    MarginLayoutParams layoutParams = (MarginLayoutParams) params;
                    layoutParams.bottomMargin -= (getPaddingBottom() - getContentPaddingBottom());
                    layoutParams.leftMargin -= (getPaddingLeft() - getContentPaddingLeft());
                    layoutParams.rightMargin -= (getPaddingRight() - getContentPaddingRight());
                    layoutParams.topMargin -= (getPaddingTop() - getContentPaddingTop());
                }
        
                super.setLayoutParams(params);
            }
        }
        

        【讨论】:

          【解决方案7】:

          只需在您的代码中添加棒棒糖前版本即可:

          if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
              {
                  cardView.setMaxCardElevation(0f);
                  cardView.setPreventCornerOverlap(false);
              }
          

          【讨论】:

            猜你喜欢
            • 2015-01-15
            • 2015-12-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-05-31
            • 1970-01-01
            • 2017-11-05
            • 1970-01-01
            相关资源
            最近更新 更多