เพิ่มเอฟเฟกต์ระลอกคลื่นให้กับปุ่มของฉันด้วยสีพื้นหลังของปุ่ม?


128

ฉันสร้างปุ่มขึ้นมาและต้องการเพิ่มเอฟเฟกต์ระลอกคลื่นให้กับปุ่มนั้น!

ฉันสร้างไฟล์ XML ปุ่ม bg: (bg_btn.xml)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#FFFFFF" android:endColor="#00FF00" android:angle="270" />
<corners android:radius="3dp" />
<stroke android:width="5px" android:color="#000000" />
</shape>

และนี่คือไฟล์เอฟเฟกต์ระลอกของฉัน: (ripple_bg.xml)

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

และนี่คือปุ่มของฉันที่ฉันต้องการเพิ่มเอฟเฟกต์ระลอกคลื่น:

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="@+id/button"
android:layout_centerHorizontal="true"
android:layout_marginTop="173dp"
android:textColor="#fff"
android:background="@drawable/ripple_bg"
android:clickable="true" />

แต่หลังจากเพิ่มพื้นหลังของปุ่มเอฟเฟกต์ระลอกจะโปร่งใสและปุ่มจะแสดงเมื่อคลิกเท่านั้นดังนี้:

ก่อนคลิก

เมื่อคลิก

แต่ฉันต้องการทั้งสีพื้นหลังของปุ่มและเอฟเฟกต์ระลอกคลื่นฉันพบโค้ดนี้บางส่วนในบล็อกต่าง ๆ ของ Stack Overflow แต่ก็ยังใช้งานไม่ได้!


โปรดปรับขนาดภาพหน้าจอให้เล็กลงในครั้งต่อไป .. (ปรับขนาดก่อนอัปโหลด)
25

@ user25 คุณยังสามารถเพิ่มlหรือmลิงก์รูปภาพได้ (ดูการแก้ไขของฉัน)
Suragch

คำตอบ:


157

นี่คือ xml ที่วาดได้อีกตัวหนึ่งสำหรับผู้ที่ต้องการเพิ่มพื้นหลังไล่ระดับรัศมีมุมและเอฟเฟกต์ระลอก:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorPrimaryDark">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorPrimaryLight"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="@dimen/button_radius_large" />
        </shape>
    </item>
</ripple>

เพิ่มสิ่งนี้ลงในพื้นหลังของปุ่มของคุณ

<Button
    ...
    android:background="@drawable/button_background" />

PS: คำตอบนี้ใช้ได้กับ Android api 21 ขึ้นไป


4
@pei พวกคุณได้รับข่าวสารนี้มาจากไหน? ฉันหมายถึงคุณรู้ได้อย่างไรว่ามีองค์ประกอบ XML ที่เรียกว่า ripple เพื่อทำงานนี้?

1
เป็นแนวคิดหนึ่งที่ใช้ในการออกแบบวัสดุ กรุณาเริ่มพิมพ์แท็กรากใหม่ใน XML drawable ใน Android rippleสตูดิโอแล้วคุณควรจะสามารถมองเห็นทั้งหมดรวมทั้งแท็ก
Pei

1
ไอเทมมาส์กใช้ยังไง?
Prashant

10
ต้องใช้ api ระดับ 21
M. kazem Akhgary

2
มันใช้งานได้ แต่ไม่ได้อธิบายวิธีการทำงาน มันควรจะเกี่ยวข้องกับ id ของรายการ ควรอ้างอิง.
oiyio

157

เพิ่มแอตทริบิวต์"?attr/selectableItemBackground"ของมุมมองของคุณandroid:foregroundหากมีพื้นหลังอยู่android:clickable="true"แล้ว


ไม่ได้ผลเสมอไป แต่คุณสามารถเพิ่มพื้นหลังให้กับเอฟเฟกต์ระลอกคลื่นได้ตามที่ระบุไว้ในความคิดเห็นของคำตอบที่ยอมรับ
Tyler

ฉันต้องใช้วิธีนี้เนื่องจากฉันใช้พื้นหลังที่กำหนดเองสำหรับปุ่มของฉัน มันใช้งานได้ดี
bnayagrawal

@ROAR ถูกต้อง แต่อย่างน้อย: "นี่ไม่ใช่ข้อผิดพลาดแอปพลิเคชันจะเพิกเฉยต่อแอตทริบิวต์อย่างไรก็ตามหากแอตทริบิวต์มีความสำคัญต่อรูปลักษณ์หรือฟังก์ชันการทำงานของแอปพลิเคชันของคุณคุณควรพิจารณาหาวิธีอื่นในการบรรลุ ผลลัพธ์เดียวกันกับแอตทริบิวต์ที่มีอยู่เท่านั้นจากนั้นคุณสามารถเลือกที่จะสร้างสำเนาของเค้าโครงในโฟลเดอร์ layout-vNN ซึ่งจะใช้กับ API NN หรือสูงกว่าซึ่งคุณสามารถใช้ประโยชน์จากแอตทริบิวต์ที่ใหม่กว่าได้ " ดังนั้นจึงทำงานได้ดีบนอุปกรณ์ที่สูงกว่า API 23 และถูกละเว้นเมื่ออยู่ด้านล่าง (เราทำได้tools:ignore="UnusedAttribute)
JorgeAmVF

หากไม่มีไลบรารีที่รองรับ Android จะเป็น?android:attr/selectableItemBackground( android:attrแทนattr)
สุดสัปดาห์

1
android:foregroundแอตทริบิวต์ไม่มีผลกับระดับ API ที่ต่ำกว่า 23
Vadim Kotov

68

เพิ่ม Ripple Effect / Animation ให้กับปุ่ม Android

เพียงแค่แทนที่แอตทริบิวต์พื้นหลังปุ่มของคุณด้วยandroid: background = "? attr / selectableItemBackground"และโค้ดของคุณจะมีลักษณะดังนี้

      <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/selectableItemBackground"
        android:text="New Button" />

อีกวิธีหนึ่งในการเพิ่ม Ripple Effect / Animation ให้กับปุ่ม Android

ด้วยวิธีนี้คุณสามารถปรับแต่งสีเอฟเฟกต์ระลอกคลื่นได้ ขั้นแรกคุณต้องสร้างไฟล์ xml ในไดเร็กทอรีทรัพยากรที่วาดได้ของคุณ สร้างไฟล์ ripple_effect.xml และเพิ่มรหัสต่อไปนี้ ความละเอียด / drawable / ripple_effect.xml

<?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="#f816a463"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="#f816a463" />
        </shape>
    </item>
</ripple>

และตั้งค่าพื้นหลังของปุ่มให้อยู่เหนือไฟล์ทรัพยากรที่วาดได้

<Button
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/ripple_effect"
    android:padding="16dp"
    android:text="New Button" />

1
สำหรับฉันไม่ปรากฏเอฟเฟกต์ระลอกคลื่น มันเป็นเพียงสวิตช์สีสำหรับปุ่ม: / เวอร์ชัน Android ของฉันคือ 5.1.1 ดังนั้นจึงควรใช้งานได้ คุณช่วยได้ไหม? ฉันทำตามขั้นตอนของคุณ
UrviG

android: สีควรแตกต่างจากเสากระโดง android: color หรือคุณต้องการเห็นเอฟเฟกต์ระลอก
SpyZip

2
หากคุณต้องการพื้นหลังคุณก็เพิ่มรายการอื่นในระลอกเช่น: <item android: drawable = "? attr / colorPrimary" />
Tyler

36

นอกเหนือจากโซลูชันของJigar Patelแล้วให้เพิ่มเข้าไปในripple.xmlเพื่อหลีกเลี่ยงพื้นหลังโปร่งใสของปุ่ม

<item
    android:id="@android:id/background"
    android:drawable="@color/your-color" />

xml ที่สมบูรณ์ :

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:color="@color/your-color"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/your-color" />
        </shape>
    </item>
    <item
        android:id="@android:id/background"
        android:drawable="@color/your-color" />
</ripple>

ใช้ripple.xmlนี้เป็นพื้นหลังในปุ่มของคุณ:

android:background="@drawable/ripple"

2
เราไม่จำเป็นต้องใช้ไฟล์<item android:id="@android:id/mask"> [...]. เว้นแต่คุณต้องการหน้ากากรูปไข่ ขอบคุณสำหรับคำตอบ!
Filipe Brito

<item android: id = "@ android: id / mask"> ทำอะไรต่อไปฉันสร้าง 2 องค์ประกอบที่คล้ายกันโดยมีและไม่มีแอตทริบิวต์นั้นและมีลักษณะเหมือนกันทุก
ประการ

@SartherisStormhammer จากเอกสารอย่างเป็นทางการ: หากมีการตั้งค่าเลเยอร์มาสก์เอฟเฟกต์ระลอกคลื่นจะถูกมาสก์กับเลเยอร์นั้นก่อนที่จะวาดทับคอมโพสิตของเลเยอร์ย่อยที่เหลือ หากไม่ได้ตั้งค่าเลเยอร์มาสก์เอฟเฟกต์การกระเพื่อมจะถูกมาสก์กับองค์ประกอบของเลเยอร์รอง นี่คือลิงค์developer.android.com/reference/android/graphics/drawable/…
Sudheesh R

@SudheeshR ที่ทำให้สับสนมากขึ้น
Sartheris Stormhammer

@SartherisStormhammer จากเอกสารอย่างเป็นทางการนั้นฉันคิดว่าค่อนข้างชัดเจน เอฟเฟกต์ Ripple จะวาดทับเลเยอร์เด็ก / มาสก์ โปรดอ่านเอกสารอีกครั้งคุณจะได้รับประเด็น
Sudheesh R

33

เมื่อปุ่มมีพื้นหลังจาก drawable เราสามารถเพิ่มเอฟเฟกต์ระลอกคลื่นให้กับพารามิเตอร์เบื้องหน้าได้ .. ตรวจสอบโค้ดด้านล่างว่าใช้งานได้กับปุ่มของฉันที่มีพื้นหลังที่แตกต่างกัน

    <Button
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:gravity="center"
    android:layout_centerHorizontal="true"                                                             
    android:background="@drawable/shape_login_button"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:text="@string/action_button_login"
     />

เพิ่มพารามิเตอร์ด้านล่างสำหรับเอฟเฟกต์ระลอกคลื่น

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

สำหรับการอ้างอิงโปรดดูลิงค์ด้านล่าง https://jascode.wordpress.com/2017/11/11/how-to-add-ripple-effect-to-an-android-app/


2
แอตทริบิวต์ android: เบื้องหน้าไม่มีผลต่อระดับ API ที่ต่ำกว่า 23
Ali Khaki

1
ข้อเสียเปรียบอย่างหนึ่งของวิธีนี้คือแม้ว่าพื้นหลังปุ่มของฉันจะเป็นวงรี แต่ระลอกคลื่นก็แพร่กระจายไปจนถึงขอบสี่เหลี่ยม
iCantC

14

AppCompat v7 +

หากคุณไม่นำหน้า?android:แอปของคุณจะขัดข้อง

คุณควรใช้"?android:attr/selectableItemBackground"หรือ"?android:attr/selectableItemBackgroundBorderless"ตามความต้องการของคุณ Borderlessฉันชอบ

คุณสามารถใส่ไว้ในandroid:backgroundหรือandroid:foregroundเพื่อเก็บคุณสมบัติที่มีอยู่

องค์ประกอบต้องมีandroid:clickable="true"และandroid:focusable="true"เพื่อให้สิ่งนี้ทำงานได้ แต่องค์ประกอบหลายอย่างเช่นปุ่มจะมีองค์ประกอบเหล่านี้trueโดยค่าเริ่มต้น

<Button
    ...
    android:background="@color/white"
    android:foreground="?android:attr/selectableItemBackgroundBorderless"
/>
<TextView
    ...
    android:background="?android:attr/selectableItemBackgroundBorderless"
    android:clickable="true"
    android:focusable="true"
/>

โดยทางโปรแกรม (Java)

TypedValue value = new TypedValue();
context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
myView.setBackgroundResource(value.resourceId);
myView.setFocusable(true); // If needed for view type

โดยทางโปรแกรม (Kotlin)

val value = TypedValue()
context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
myView.setBackgroundResource(value.resourceId)
myView.setFocusable(true) // If needed for view type

ฟังก์ชั่นขยาย Kotlin แบบใช้ซ้ำได้

myView.ripple()

fun View.ripple(): View {
    val value = TypedValue()
    context.theme.resolveAttribute(android.R.attr.selectableItemBackground, value, true)
    setBackgroundResource(value.resourceId)
    isFocusable = true // Required for some view types
    return this
}

7

การเพิ่มแอตทริบิวต์เบื้องหน้าและคลิกได้นั้นใช้ได้ผลสำหรับฉัน

<Button
    ... 
    android:background="@color/your_color"
    android:foreground="?attr/selectableItemBackgroundBorderless"
    android:clickable="true" />

6

นอกจากSudheesh R

เพิ่มเอฟเฟกต์ระลอกคลื่น / แอนิเมชั่นให้กับปุ่ม Android ที่มีรูปทรงสี่เหลี่ยมผืนผ้าของปุ่มพร้อมมุม

สร้างไฟล์ xml res / drawable / your_file_name.xml

<?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="@color/colorWhite"
    tools:targetApi="lollipop">
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimaryDark" />
            <corners android:radius="50dp" />
        </shape>
    </item>

    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <gradient
                android:angle="90"
                android:endColor="@color/colorAccent"
                android:startColor="@color/colorPrimary"
                android:type="linear" />
            <corners android:radius="50dp" />
        </shape>
    </item>
</ripple>

4

เมื่อคุณใช้ android: background คุณกำลังเปลี่ยนสไตล์และรูปลักษณ์ส่วนใหญ่ของปุ่มด้วยสีว่างเปล่า

อัปเดต: ในเวอร์ชัน 23.0.0 ของ AppCompat มี Widget.AppCompat ปุ่มใหม่สไตล์สีที่ใช้ colorButtonNormal ของธีมของคุณสำหรับสีที่ปิดใช้งานและ colorAccent สำหรับสีที่เปิดใช้งาน

สิ่งนี้ช่วยให้คุณนำไปใช้กับปุ่มของคุณได้โดยตรงผ่าน

<Button
 ...
style="@style/Widget.AppCompat.Button.Colored" />

คุณสามารถใช้ drawable ในไดเร็กทอรี v21 สำหรับพื้นหลังของคุณเช่น:

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?attr/colorControlHighlight">
<item android:drawable="?attr/colorPrimary"/>
</ripple>

เพื่อให้แน่ใจว่าสีพื้นหลังของคุณคือ? attr / colorPrimary และมีภาพเคลื่อนไหวระลอกเริ่มต้นโดยใช้ค่าเริ่มต้น? attr / colorControlHighlight (ซึ่งคุณสามารถตั้งค่าในธีมของคุณได้หากต้องการ)

หมายเหตุ: คุณจะต้องสร้างตัวเลือกที่กำหนดเองให้น้อยกว่า v21:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/primaryPressed"            android:state_pressed="true"/>
<item android:drawable="@color/primaryFocused" android:state_focused="true"/>
<item android:drawable="@color/primary"/>
</selector>

ฉันใช้ minSDK lvl 21
rakcode

ไม่มีโฟลเดอร์ที่วาดได้ v21 มีเพียงโฟลเดอร์เดียวเท่านั้นที่โฟลเดอร์นั้นเองโฟลเดอร์
v21

ใช่ฉันใช้ API นี้ด้วยถ้าฉันใช้ API นี้หลังจากคลิกแอปของฉันขัดข้อง
rakcode

จริงๆแล้วฉันกำลังทดสอบแอปของฉันในโทรศัพท์ด้วยโหมดดีบักและระบบปฏิบัติการของฉันคือ CyanogenMod13 (Android 6, Marshmellow)
rakcode

4

ลองดู

<Button
            android:id="@+id/btn_location"
            android:layout_width="121dp"
            android:layout_height="38dp"
            android:layout_gravity="center"
            android:layout_marginBottom="24dp"
            android:layout_marginTop="24dp"
            android:foreground="?attr/selectableItemBackgroundBorderless"
            android:clickable="true"
            android:background="@drawable/btn_corner"
            android:gravity="center_vertical|center_horizontal"
            android:paddingLeft="13dp"
            android:paddingRight="13dp"
            android:text="Save"
            android:textColor="@color/color_white" />

4

แนวทางง่ายๆคือกำหนดธีมมุมมองตามที่อธิบายไว้ที่นี่ที่นี่

some_view.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="?attr/selectableItemBackgroundBorderless"
   android:focusable="true"
   android:src="@drawable/up_arrow"
   android:theme="@style/SomeButtonTheme"/>

some_style.xml

<style name="SomeButtonTheme" >
   <item name="colorControlHighlight">@color/someColor</item>
</style>

3

เพียงใช้:

android:backgroundTint="#f816a463"

แทน:

android:background="#f816a463"

อย่าลืมเปลี่ยนButtonเป็นandroid.support.v7.widget.AppCompatButton


1
ข้อเสียคือถ้าคุณต้องการปุ่มเพื่อเติมเต็มหน้าจอแนวนอน 100% คุณจะไม่ทำ
Filipe Brito

1

ทางเลือกอื่นในการใช้ไฟล์ <ripple>แท็ก (ซึ่งโดยส่วนตัวแล้วฉันไม่ต้องการทำเพราะสีไม่ใช่ "ค่าเริ่มต้น") มีดังต่อไปนี้:

สร้างสิ่งที่วาดได้สำหรับพื้นหลังของปุ่มและรวม<item android:drawable="?attr/selectableItemBackground">ไว้ในไฟล์<layer-list>

จากนั้น (และฉันคิดว่านี่เป็นส่วนสำคัญ) ตั้งค่าทางโปรแกรมbackgroundResource(R.drawable.custom_button)บนอินสแตนซ์ปุ่มของคุณ

กิจกรรม / Fragment

Button btn_temp = view.findViewById(R.id.btn_temp);
btn_temp.setBackgroundResource(R.drawable.custom_button);

แบบ

<Button
    android:id="@+id/btn_temp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/custom_button"
    android:text="Test" />

custom_button.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>
    <item android:drawable="?attr/selectableItemBackground" />
</layer-list>

เหตุใดจึงควรตั้งค่า backgroundResource ของโปรแกรมอีกครั้งในขณะที่รูปแบบ xml กำหนดพื้นหลังของปุ่ม
SunnyShiny9
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.