Android L's Ripple Effect - Touch Feedback for Buttons - Using XML

前端 未结 7 1524
青春惊慌失措
青春惊慌失措 2020-11-27 11:13

I am trying to understand how to implement the \"Ripple Effect - Touch Feedback\" for buttons and other views. I looked at the questions related to Ripple touch effect on SO

相关标签:
7条回答
  • 2020-11-27 11:49

    Slight addition to above answer: Note that the mask color is not used in any way.

    You can do more complicated things with ripple as well. For example, if you wanted a border on your ripple button you can use it like a layer-list.

    <ripple
        xmlns:android="http://schemas.android.com/apk/res/android" 
        android:color="?android:colorControlHighlight">
    
        <!-- Note: <ripple> acts like a layer-list -->
        <item android:id="@android:id/mask">
            <shape android:shape="oval">
                <!-- This color is not displayed in any way -->
                <solid android:color="@android:color/black" />
            </shape>
        </item>
    
        <!-- This is the border -->
        <item>
            <shape android:shape="rectangle">
                <corners android:radius="3dp"/>
                <!-- Use your border color in place of #f00 -->
                <stroke android:width="1dp" android:color="#f00"/>
            </shape>
        </item>
     </ripple>
    

    Note that the element with id @android:id/mask is only used to show where the ripple effect will stop at. If you wanted it to cover the whole button, you could change the android:shape to be rectangle. You can imagine doing many more interesting things with this as well!

    Also make sure to have a backup drawable for devices that aren't 21 yet or the app will crash on old devices.

    0 讨论(0)
  • 2020-11-27 11:49

    The best way to use this in android:foreground, because it allows you use own background also.

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

    Example:

    <android.support.v7.widget.AppCompatButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:background="@color/button.normal"
        android:textColor="@color/white"/>
    
    0 讨论(0)
  • 2020-11-27 11:55

    UPDATE Material Components:

    With the Material Components Library it is very easy to apply a ripple.
    Just use the MaterialButton and the app:rippleColor attribute:

    <com.google.android.material.button.MaterialButton
        app:rippleColor="@color/my_selector"
        ../>
    

    With a selector like this:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
      <item android:alpha="..." android:color="?attr/colorOnPrimary" android:state_pressed="true"/>
      <item android:alpha="..." android:color="?attr/colorOnPrimary" android:state_focused="true" android:state_hovered="true"/>
      <item android:alpha="..." android:color="?attr/colorOnPrimary" android:state_focused="true"/>
      <item android:alpha="..." android:color="?attr/colorOnPrimary" android:state_hovered="true"/>
      <item android:alpha="..." android:color="?attr/colorOnPrimary"/>
    
    </selector>
    

    Old answer
    You can do something like this:

    <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:background="@drawable/ripple"
          
        />
    

    Where the ripple.xml is:

    <ripple xmlns:android="http://schemas.android.com/apk/res/android" 
                          android:color="?android:colorControlHighlight">
            <item android:id="@android:id/mask">
                <shape android:shape="oval">
                    <solid android:color="?android:colorAccent" />
                </shape>
            </item>
     </ripple>
    
    0 讨论(0)
  • 2020-11-27 11:58

    You can add clickable as true and background or foreround as ?attr/selectableItemBackground attributes to the view:

    <Button
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="Button"
         android:clickable="true"
         android:background="?attr/selectableItemBackground"
         android:textColor="@android:color/white"/>
    

    If in case your view already has a background filled with something, you could fill your foreground with selectableItemBackground

    <Button
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="Button"
         android:clickable="true"
         android:foreground="?attr/selectableItemBackground"
         android:background="@color/colorPrimary"
         android:textColor="@android:color/white"/>
    
    0 讨论(0)
  • 2020-11-27 12:04

    For lollipop(API>21) make file as btn_ripple_effect.xml in drawable and put below code

    <?xml version="1.0" encoding="utf-8"?>
    
    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:color="?android:colorAccent"
        tools:targetApi="lollipop">
        <item android:drawable="@color/cancel_btn_clr" /> <!-- default -->
        <item android:id="@android:id/mask">
            <shape android:shape="rectangle">
                <solid android:color="?android:colorAccent" />
            </shape>
        </item>
    </ripple>
    

    For pre lollipop (API<21)make file as btn_ripple_effect.xml in drawable-v21 folder and put below code

    <?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/colorAccent"></solid>
            </shape>
        </item>
    
        <item>
            <shape>
                <solid android:color="@color/cancel_btn_clr"></solid>
            </shape>
        </item>
    
    </selector>
    
    0 讨论(0)
  • 2020-11-27 12:06

    I was researching ripple effect as it was something I wanted to apply to a few buttons in my application and happened across your post. While your question is searching for an answer as to how to add the ripple effect using XML that was actually something I was trying to avoid as when trying to add that attribute you see it requires v21.

    If you are targeting lower than v21 than that new class extending Button (or ImageButton, etc.) will avoid complaints from the compiler.

    As there was no explanation on how to implement the custom class above I thought I would fill in. All you need to do is create the new class and then in the XML change "Button" to "the.package.name.MyButton".

    From:

     <Button
        android:id="@+id/Button"     
    
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    

    To:

     <the.package.name.MyButton
       android:id="@+id/Button"     
    
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    

    That's it. Now your button when pressed will have a ripple contained within its bounds.

    I like this approach I just wish the ripple would extend pass the bounds. For a small button this ripple effect really highlights how square or rectangular the button really is. Visually it would be more satisfying if the ripple just continued until it reached its full radius.

    0 讨论(0)
提交回复
热议问题