【问题标题】:Ripple effect on Android Lollipop CardViewAndroid Lollipop CardView 上的波纹效果
【发布时间】:2015-01-12 13:53:41
【问题描述】:

我试图通过设置活动 XML 文件中的 android:backgound 属性来让 CardView 在触摸时显示涟漪效果,如 Android 开发者页面上的 here 所述,但它不起作用。根本没有动画,但是调用了onClick中的方法。我也尝试按照here 的建议创建一个ripple.xml 文件,但结果相同。

活动的 XML 文件中显示的 CardView:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="155dp"
    android:layout_height="230dp"
    android:elevation="4dp"
    android:translationZ="5dp"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:onClick="showNotices"
    android:background="?android:attr/selectableItemBackground"
    android:id="@+id/notices_card"
    card_view:cardCornerRadius="2dp">

</android.support.v7.widget.CardView> 

我对 android 开发比较陌生,所以我可能犯了一些明显的错误。

【问题讨论】:

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


    【解决方案1】:

    您应该将以下内容添加到CardView:

    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    

    【讨论】:

    • 适用于具有涟漪效果的棒棒糖,但在旧平台上运行时仅提供纯色。对我来说已经足够了:)
    • 一点观察:我注意到 clickable 属性不是必需的,甚至可以破坏一些东西!我有一个充满可点击 CardViews 的 GridView,并且监听器无法正常工作。我从 XML 中删除了可点击标签,现在一切正常
    • @joaquin 没有可点击,它导致波纹仅来自中心
    • 在没有android:clickable="true" 的情况下工作。
    • 为 CardView 更好用?attr/selectableItemBackgroundBorderless
    【解决方案2】:

    将这两行代码添加到您的 xml 视图中,以在您的 cardView 上产生涟漪效果。

    android:clickable="true"
    android:foreground="?android:attr/selectableItemBackground"
    

    【讨论】:

    • 太棒了! foreground 与自定义背景视图一起工作,就像一个魅力!不错!
    • 不要重复同样的答案!
    【解决方案3】:

    我设法通过以下方式获得了卡片视图的连锁反应:

    <android.support.v7.widget.CardView 
        xmlns:card_view="http://schemas.android.com/apk/res-auto" 
        android:clickable="true" 
        android:foreground="@drawable/custom_bg"/>
    

    对于您可以在上面的代码中看到的 custom_bg,您必须为 lollipop(在 drawable-v21 包中)和 pre-lollipop(在 drawable 包中)设备定义一个 xml 文件。 对于 drawable-v21 包中的 custom_bg,代码为:

    <ripple 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:attr/colorControlHighlight">
    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white"/>
    </ripple>
    

    drawable包中的custom_bg,代码为:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <item android:state_pressed="true">
        <shape>
            <solid android:color="@color/colorHighlight"></solid>
        </shape>
    </item>
    <item>
        <shape>
            <solid android:color="@color/navigation_drawer_background"></solid>
        </shape>
    </item>
    </selector>
    

    因此,在棒棒糖之前的设备上,您将获得稳定的点击效果,而在棒棒糖设备上,您将在卡片视图上产生涟漪效果。

    【讨论】:

    • 嗨,我意识到通过在 CardView 的前台应用选择器(或波纹),它会阻止 CardView 本身中的子级 - stackoverflow.com/questions/33763403/… 我知道你遇到和我一样的问题吗?或者,我错过了什么?谢谢。
    • @CheokYanCheng:我没有遇到像你这样的问题,但我会根据个人经验说 cardView 有一些棒棒糖前的错误。避免在棒棒糖前使用 cardview:elevation 属性。以上对我和其他支持者来说都很好。
    • 请问,您的 colorHighlight 和 navigation_drawer_background 的值是多少。如果您使用自己定义的没有透明度的颜色,您还能看到卡片的孩子吗?
    • @CheokYanCheng :值如下,​​#FFFFFF#FF8A65
    • 我不为我的案子工作。我使用您的选择器作为前景。正如预期的那样,用作卡片视图前景的纯白色 (navigation_drawer_background) 将阻止所有子视图的可见性 - i.imgur.com/CleYh5B.png 这是不应用选择器作为前景时的样子 - i.imgur.com/ZXk5Aoq.png
    【解决方案4】:

    在您正在使用的 appcompat 支持库中省略了涟漪效应。如果您想查看涟漪效果,请使用 Android L 版本并在 Android L 设备上进行测试。根据 AppCompat v7 网站:

    “为什么棒棒糖之前没有涟漪? 很多让 RippleDrawable 顺利运行的原因是 Android 5.0 的新 RenderThread。为了优化旧版 Android 的性能,我们暂时不使用 RippleDrawable。”

    查看此链接here 了解更多信息

    【讨论】:

    • 就是这样。谢谢!
    • 那么你会如何在 cardView for Android Lollipop 上添加涟漪效应呢?
    • 所以我必须决定是使用 appcompat 向后兼容还是使用所有新效果,使用来自 android 核心的类但将自己限制为 API 21?
    • 您可以制作 2 个 APK,一个用于 21+,另一个用于
    • 这就是为什么编写“纯”Android L 应用程序目前不可行的原因。截至 2015 年 7 月,您的目标用户群将达到 12%。
    【解决方案5】:

    如果你正在使用的应用minSdkVersion是9级,你可以使用:

    android:foreground="?selectableItemBackground"
    android:clickable="true"
    

    相反,从第 11 级开始,您使用:

    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    

    来自文档:

    clickable - 定义此视图是否响应点击事件。必须是布尔值,“真”或“假”。

    foreground - 定义绘制内容的可绘制对象。这可以用作叠加层。如果重力设置为填充,则前景可绘制对象参与内容的填充。

    【讨论】:

    • 使用 android:foreground="?android:attr/selectableItemBackground" 有助于 AndroidX 兼容性,谢谢!
    【解决方案6】:

    改用 Material Cardview,它扩展了 Cardview 并提供了多项新功能,包括默认可点击效果:

    <com.google.android.material.card.MaterialCardView>
    
    ...
    
    </com.google.android.material.card.MaterialCardView>
    

    依赖关系(可以使用到 API 14 以支持旧设备):

    implementation 'com.google.android.material:material:1.0.0'
    

    【讨论】:

    • 你是对的。不要忘记添加 android:clickable="true" 和 android:focusable="true"
    【解决方案7】:

    对我来说,将foreground 添加到CardView 不起作用(原因未知:/)

    将相同的内容添加到它的子布局中就可以了。

    代码:

    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:focusable="true"
        android:clickable="true"
        card_view:cardCornerRadius="@dimen/card_corner_radius"
        card_view:cardUseCompatPadding="true">
    
        <LinearLayout
            android:id="@+id/card_item"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:foreground="?android:attr/selectableItemBackground"
            android:padding="@dimen/card_padding">
    
        </LinearLayout>
    </android.support.v7.widget.CardView>
    

    【讨论】:

    • 那是因为孩子拦截了事件,如果你尝试像在cardview中添加填充(比如20dp),然后你点击填充的部分,那么你会看到即使没有设置前景属性的孩子也会产生涟漪效应
    • 这也适用于我,使用新的材料组件:com.google.android.material.card.MaterialCardView。我有一个用于卡片视图的高程 stateListAnimator 来调整高程,并将波纹应用于内部约束布局,前景中的可选项目背景没有可点击属性。
    • 我现在不记得了,但是有一种方法可以设置子视图不对点击事件做出反应
    【解决方案8】:

    添加这两行代码就像任何视图(如 Button、Linear Layout 或 CardView)的魅力只需将这两行代码放在一起,看看它的神奇之处...

    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    

    【讨论】:

      【解决方案9】:

      将以下内容添加到您的 xml:

      android:clickable="true"
      android:focusable="true"
      android:background="?android:attr/selectableItemBackground"
      

      并添加到您的适配器(如果是您的情况)

          override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                  val attrs = intArrayOf(R.attr.selectableItemBackground)
                  val typedArray = holder.itemView.context.obtainStyledAttributes(attrs)
                  val selectableItemBackground = typedArray.getResourceId(0, 0)
                  typedArray.recycle()
      
                  holder.itemView.isClickable = true
                  holder.itemView.isFocusable = true
                  holder.itemView.foreground = holder.itemView.context.getDrawable(selectableItemBackground)
              }
          }
      

      【讨论】:

        【解决方案10】:

        如果有一个像RelativeLayout 或LinearLayout 这样的根布局包含了CardView 中所有适配器项的组件,则必须在该根布局中设置背景属性。喜欢:

        <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="122dp"
        android:layout_marginBottom="6dp"
        android:layout_marginLeft="6dp"
        android:layout_marginRight="6dp"
        card_view:cardCornerRadius="4dp">
        
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/touch_bg"/>
        </android.support.v7.widget.CardView>
        

        【讨论】:

          【解决方案11】:

          对于那些在 RecyclerView 中显示的以编程方式创建的 CardView(或者在我的情况下扩展 CardView 的自定义视图)无法工作的涟漪效应问题的解决方案的人来说,以下内容对我有用。基本上,在 XML 布局文件中以声明方式声明其他答案中提到的 XML 属性似乎不适用于以编程方式创建的 CardView 或从自定义布局创建的 CardView(即使根视图是 CardView 或使用了合并元素),所以它们必须像这样以编程方式设置:

          private class MadeUpCardViewHolder extends RecyclerView.ViewHolder {
              private MadeUpCardView cardView;
          
              public MadeUpCardViewHolder(View v){
                  super(v);
          
                  this.cardView = (MadeUpCardView)v;
          
                  // Declaring in XML Layout doesn't seem to work in RecyclerViews
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                      int[] attrs = new int[]{R.attr.selectableItemBackground};
                      TypedArray typedArray = context.obtainStyledAttributes(attrs);
                      int selectableItemBackground = typedArray.getResourceId(0, 0);
                      typedArray.recycle();
          
                      this.cardView.setForeground(context.getDrawable(selectableItemBackground));
                      this.cardView.setClickable(true);
                  }
              }
          }
          

          MadeupCardView extends CardView 向 this answer 致敬 TypedArray 部分。

          【讨论】:

          • 感谢您的回答。在我的情况下,我通过以编程方式仅将可点击和可聚焦设置为 true 使其工作,它开始在我的自定义视图上显示涟漪效应(视图的父级是 MaterialCardView)
          【解决方案12】:

          Ripple 用于 android Cardview 控件的事件:

          <android.support.v7.widget.CardView
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:layout_gravity="center"
              android:foreground="?android:attr/selectableItemBackground"
              android:clickable="true"
              android:layout_marginBottom="4dp"
              android:layout_marginTop="4dp" />
          

          【讨论】:

            【解决方案13】:

            我对 AppCompat 不满意,所以我编写了自己的 CardView 并向后移植了波纹。它在 Galaxy S 上与 Gingerbread 一起运行,所以这绝对是可能的。

            更多详情请查看source code。

            【讨论】:

            • 链接失效
            【解决方案14】:
              android:foreground="?android:attr/selectableItemBackgroundBorderless"
               android:clickable="true"
               android:focusable="true"
            

            仅工作 api 21 并使用此不使用此列表行卡视图

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2022-01-19
              • 2017-05-01
              • 1970-01-01
              • 2017-05-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多