วิธีตั้งค่าเอฟเฟกต์การคลิกปุ่มใน Android


105

ใน Android เมื่อฉันตั้งค่าภาพพื้นหลังเป็นปุ่มฉันไม่เห็นเอฟเฟกต์ใด ๆ บนปุ่ม

ฉันต้องการเอฟเฟกต์บางอย่างบนปุ่มเพื่อให้ผู้ใช้รับรู้ว่ามีการคลิกปุ่มนั้น

ปุ่มควรจะมืดสักครู่เมื่อคลิกแล้วควรทำอย่างไร

ขอบคุณ.



วิธีต่อไปนี้ช่วยให้คุณใช้ styleclass เดียวเพื่อสกินปุ่มทั้งหมดของคุณโดยไม่คำนึงถึงข้อความ: stackoverflow.com/questions/5327553/…
Zack Marrapese

ไม่ฉันไม่ได้ใช้ปุ่มรูปภาพฉันกำลังใช้ปุ่มปกติสำหรับสิ่งนี้หรือไม่?
Jignesh Ansodariya

3
บทช่วยสอนที่ดีมาก: dibbus.com/2011/02/gradient-buttons-for-android
Pratik Butani

คำตอบ:


157

สิ่งนี้สามารถทำได้โดยการสร้างไฟล์ xml ที่วาดได้ซึ่งมีรายการสถานะสำหรับปุ่ม ตัวอย่างเช่นหากคุณสร้างไฟล์ xml ใหม่ชื่อ "button.xml" ด้วยรหัสต่อไปนี้:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/YOURIMAGE" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/gradient" />
    <item android:drawable="@drawable/YOURIMAGE" />
</selector>

หากต้องการให้ภาพพื้นหลังมีลักษณะมืดลงเมื่อกดให้สร้างไฟล์ xml ที่สองและเรียกมันว่า gradient.xml ด้วยรหัสต่อไปนี้:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <bitmap android:src="@drawable/YOURIMAGE"/>
    </item>
    <item>
        <shape xmlns:android="http://schemas.android.com/apk/res/android">
            <gradient android:angle="90" android:startColor="#880f0f10" android:centerColor="#880d0d0f" android:endColor="#885d5d5e"/>
        </shape>
    </item>
</layer-list>

ใน xml ของปุ่มของคุณตั้งค่าพื้นหลังเป็นปุ่ม xml เช่น

android:background="@drawable/button"

หวังว่านี่จะช่วยได้!

แก้ไข: เปลี่ยนรหัสด้านบนเพื่อแสดงรูปภาพ (YOURIMAGE) ในปุ่มซึ่งตรงข้ามกับสีบล็อก


แล้วฉันจะตั้งค่ารูปภาพสำหรับพื้นหลังปุ่มได้ที่ไหนเพื่อตั้งค่ารูปภาพจะต้อง
Jignesh Ansodariya

1
แก้ไขเพื่อแสดงวิธีใช้ภาพพื้นหลังกับสถานะ XML แทนที่ YOURIMAGE ด้วยทรัพยากรรูปภาพในไดเร็กทอรี drawable ของคุณ
Ljdawson

สิ่งนี้ใช้ได้เฉพาะเมื่อ src ของปุ่มเป็นรูปสี่เหลี่ยมผืนผ้า หาก src ที่วาดได้มีรูปร่างแตกต่างไปจากนั้นการไล่ระดับสีจะถูกนำไปใช้กับพื้นหลังด้วยและนี่ก็เป็นเรื่องน่าเศร้า
Renato Lochetti

ไม่จริง ๆ สามารถใช้รูปร่างอื่นในรายการเลเยอร์ได้
เสมอ

2
ในขณะที่ฉันใช้รูปภาพมันใช้ได้กับฉัน .. แต่เมื่อฉันใช้พื้นหลัง Xml มันไม่ทำงาน ...
DKV

88

จะง่ายกว่าเมื่อคุณมีปุ่มรูปภาพจำนวนมากและคุณไม่ต้องการเขียน xml-s สำหรับทุกปุ่ม

Kotlin เวอร์ชัน:

fun buttonEffect(button: View) {
    button.setOnTouchListener { v, event ->
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                v.background.setColorFilter(-0x1f0b8adf, PorterDuff.Mode.SRC_ATOP)
                v.invalidate()
            }
            MotionEvent.ACTION_UP -> {
                v.background.clearColorFilter()
                v.invalidate()
            }
        }
        false
    }
}

เวอร์ชัน Java:

public static void buttonEffect(View button){
    button.setOnTouchListener(new OnTouchListener() {

        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(0xe0f47521,PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.getBackground().clearColorFilter();
                    v.invalidate();
                    break;
                }
            }
            return false;
        }
    });
}

2
ฉันใช้สิ่งนี้ในโค้ดของฉันและปัญหาเดียวที่ฉันสังเกตเห็นจนถึงตอนนี้คือปุ่มทำงานแปลก ๆ เมื่อวางไว้ใน ScrollView
Finnboy11

เป็นทางออกที่ยอดเยี่ยมจริงๆและนี่ควรเป็นคำตอบที่ถูกต้อง
Biraj Zalavadia

ดีกว่านี้ยังไง การออกแบบควรเก็บไว้นอกรหัสไม่ใช่หรือ?
Bugs Happen

เป็นเพียงวิธีง่ายๆสำหรับปัญหานี้ เมื่อคุณมีปุ่มจำนวนมากและคุณไม่ต้องการสร้าง xml สำหรับทุกๆปุ่มมันอาจเป็นประโยชน์
András

พระเจ้าช่วย! ลองนึกภาพว่ามีปุ่ม 5 ปุ่มในชิ้นส่วน ... คุณจะมีรหัสสำเร็จรูปนี้ทั้งหมด ... จะ refactor ได้อย่างไร? เปลี่ยนฟิลเตอร์สีสำหรับปุ่มทั้งหมดในกิจกรรมทั้งหมดหรือไม่? อิมโฮนักพัฒนาคนต่อไปของคุณจะไม่มีความสุขขนาดนี้ ..
Leo Droidcoder

84

สร้างAlphaAnimationวัตถุของคุณที่กำหนดว่าจะมีเอฟเฟกต์การซีดจางของปุ่มมากแค่ไหนจากนั้นปล่อยให้มันเริ่มต้นในonClickListenerปุ่มของคุณ

ตัวอย่างเช่น :

private AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);

// some code

public void onClick(View v) {
    v.startAnimation(buttonClick);
}

แน่นอนว่านี่เป็นเพียงวิธีเดียวไม่ใช่วิธีที่ต้องการมากที่สุดมันง่ายกว่า


5
สิ่งที่ฉันชอบเกี่ยวกับโซลูชันนี้คือไม่จำเป็นต้องสร้างตัวเลือกจำนวนมากเมื่อคุณมีปุ่มหลายปุ่มพร้อมรูปภาพที่กำหนดเอง
พีท

2
สิ่งนี้จะไม่ทำให้ปุ่มจางลงเมื่อแตะลง แต่จะจางลงเพียงเสี้ยววินาทีหลังจากตรวจพบการคลิกและนิ้วของผู้ใช้ถูกยกขึ้นแล้ว
Doug Voss

1
สวยและเรียบง่าย

@ Doug Voss คุณสามารถกำหนดระยะเวลาของแอนิเมชั่นให้ยาวขึ้นได้
Ahmed Adel Ismail

แล้ว onLongClick และ 'circularReveal' ล่ะ?
Acauã Pitta

46

คุณสามารถใช้เบื้องหน้าของคุณViewเพื่อให้บรรลุผลที่สามารถคลิกได้:

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


สำหรับใช้กับธีมสีเข้มให้เพิ่มธีมให้กับคุณlayout(เพื่อให้เอฟเฟกต์คลิกได้ชัดเจน):

android:theme="@android:style/ThemeOverlay.Material.Dark"

5
วิธีที่ง่ายที่สุดในการใช้งาน FYI, Attribute android: ส่วนหน้าไม่มีผลกับระดับ API ที่ต่ำกว่า 23
dolgom

1
วิธีแก้ปัญหาที่ง่ายที่สุด
Jerry Chong

2
นี่ควรเป็นคำตอบที่ยอมรับง่ายกว่ามากและเพิ่มเอฟเฟกต์ภาพเคลื่อนไหวระลอกคลื่นที่ดี
Tyler

1
@dolgom สำหรับระดับ API <23 ให้ใช้ในแอตทริบิวต์ "background" ดังนั้น: android: background = "? android: attr / selectableItemBackground"
Z3R0

24

เพื่อให้รายการของคุณสอดคล้องกับรูปลักษณ์ของระบบให้ลองอ้างอิงแอตทริบิวต์ของระบบandroid:attr/selectableItemBackgroundในพื้นหลังหรือแท็กเบื้องหน้าของมุมมองที่คุณต้องการ:

<ImageView
    ...
    android:background="?android:attr/selectableItemBackground"      
    android:foreground="?android:attr/selectableItemBackground"
    ...
/>

ใช้แอตทริบิวต์ทั้งสองเพื่อให้ได้เอฟเฟกต์ที่ต้องการก่อน / หลัง API ระดับ 23 ตามลำดับ

https://stackoverflow.com/a/11513474/4683601


2
วิธีแก้ปัญหาที่ง่ายที่สุด ขอบคุณ!
tykom

9

หรือใช้ภาพพื้นหลังเพียงภาพเดียวคุณสามารถสร้างเอฟเฟกต์การคลิกได้โดยใช้ setOnTouchListener

สองทาง

((Button)findViewById(R.id.testBth)).setOnTouchListener(new OnTouchListener() {

      @Override
        public boolean onTouch(View v, MotionEvent event) {
          switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN: {
                  Button view = (Button) v;
                  view.getBackground().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP);
                  v.invalidate();
                  break;
              }
              case MotionEvent.ACTION_UP:
                  // Your action here on button click
              case MotionEvent.ACTION_CANCEL: {
                  Button view = (Button) v;
                  view.getBackground().clearColorFilter();
                  view.invalidate();
                  break;
              }
          }
          return true;
        }
});

ป้อนคำอธิบายภาพที่นี่

และถ้าคุณไม่ต้องการใช้setOnTouchListerอีกวิธีหนึ่งในการบรรลุเป้าหมายนี้คือ

    myButton.getBackground().setColorFilter(.setColorFilter(0xF00, Mode.MULTIPLY);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {android.R.attr.defaultValue}, myButton);

    myButton.setBackgroundDrawable(listDrawable);

มีข้อผิดพลาดในโค้ดในวิธีที่ 2 ฟังก์ชัน getCurrent () คืออะไร? myButton ยังไม่ใช่ Drawable ดังนั้นจึงไม่สามารถเพิ่มเป็นสถานะได้
Ehtesham Hasan

ขอขอบคุณที่ชี้ให้เห็นข้อผิดพลาด ฉันได้แก้ไขแล้วและ myButton เป็นอินสแตนซ์ของคลาสปุ่มที่ให้เมธอด setBackgroundDrawable และใช้อินสแตนซ์ Drawable ดังนั้นสิ่งนี้จะได้ผล
Vinayak Bevinakatti

ตรวจสอบคำตอบของฉันซึ่งเป็นไปตามแนวทางที่ 2 ของคุณ stackoverflow.com/a/39430738/5229515
Ehtesham Hasan

ซึ่งน่าจะมี "return false" ในตอนท้ายเพื่อไม่ให้ใช้งานเหตุการณ์และสามารถเรียก onClickListeners เพิ่มเติมได้
Doug Voss

3

เพียงแค่ต้องการเพิ่มวิธีง่ายๆในการทำสิ่งนี้: หาก ImageButton ของคุณยังคงเป็นพื้นหลังและคุณไม่ได้ตั้งค่าเป็นค่าว่างมันจะทำงานเหมือนปุ่มปกติและจะแสดงภาพเคลื่อนไหวการคลิกในขณะที่คลิกเหมือนกับปุ่มอื่น ๆ พื้นหลังขณะที่ยังอยู่ที่นั่น:

<ImageButton
    android:id="@+id/imageButton2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingBottom="1dp"
    android:paddingLeft="1dp"
    android:paddingRight="1dp"
    android:paddingTop="1dp"
    android:src="@drawable/squareicon" />

พายจะไม่ปล่อยให้มองเห็นพื้นหลังและทำให้ปุ่มทำงานเหมือนกับปุ่มอื่น ๆ


1
สิ่งนี้จะทำให้เส้นขอบของปุ่มสี่เหลี่ยมอยู่รอบ ๆ รูปภาพหากเป็นวงกลม
MSaudi

3

นี่เป็นทางออกที่ดีที่สุดที่ฉันได้รับคำแนะนำจากคำตอบของ @ Vinayak โซลูชันอื่น ๆ ทั้งหมดมีข้อเสียที่แตกต่างกัน

ก่อนอื่นให้สร้างฟังก์ชันเช่นนี้

void addClickEffect(View view)
{
    Drawable drawableNormal = view.getBackground();

    Drawable drawablePressed = view.getBackground().getConstantState().newDrawable();
    drawablePressed.mutate();
    drawablePressed.setColorFilter(Color.argb(50, 0, 0, 0), PorterDuff.Mode.SRC_ATOP);

    StateListDrawable listDrawable = new StateListDrawable();
    listDrawable.addState(new int[] {android.R.attr.state_pressed}, drawablePressed);
    listDrawable.addState(new int[] {}, drawableNormal);
    view.setBackground(listDrawable);
}

คำอธิบาย:

getConstantState (). newDrawable () ใช้เพื่อโคลน Drawable ที่มีอยู่มิฉะนั้นจะใช้ drawable เดียวกัน อ่านเพิ่มเติมจากที่นี่: Android: การโคลนสิ่งที่วาดได้เพื่อสร้าง StateListDrawable ด้วยตัวกรอง

mutate () ใช้เพื่อทำให้ Drawable clone ไม่เปิดเผยสถานะกับอินสแตนซ์อื่น ๆ ของ Drawable อ่านเพิ่มเติมได้ที่นี่: https://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate ()

การใช้งาน:

คุณสามารถส่ง View ประเภทใดก็ได้ (Button, ImageButton, View ฯลฯ ) เป็นพารามิเตอร์ไปยังฟังก์ชันและจะได้รับเอฟเฟกต์การคลิกที่นำไปใช้กับพวกเขา

addClickEffect(myButton);
addClickEffect(myImageButton);

2
Step: set a button in XML with onClick Action:

 <Button
android:id="@+id/btnEditUserInfo"
style="?android:borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="@dimen/txt_height"
android:layout_gravity="center"
android:background="@drawable/round_btn"
android:contentDescription="@string/image_view"
android:onClick="edit_user_info"
android:text="Edit"
android:textColor="#000"
android:textSize="@dimen/login_textSize" />

Step: on button clicked show animation point
//pgrm mark ---- ---- ----- ---- ---- ----- ---- ---- -----  ---- ---- -----

    public void edit_user_info(View view) {

        // show click effect on button pressed
        final AlphaAnimation buttonClick = new AlphaAnimation(1F, 0.8F);
        view.startAnimation(buttonClick);

        Intent intent = new Intent(getApplicationContext(),  EditUserInfo.class);
        startActivity(intent);

    }// end edit_user_info

2

ใช้ RippleDrawable สำหรับสถานะการออกแบบวัสดุเอฟเฟกต์แบบกด / คลิก

เพื่อให้บรรลุสิ่งนี้ให้สร้างรายการระลอกเป็น. xml ภายใต้โฟลเดอร์ / drawable และใช้ใน android: background สำหรับมุมมองใด ๆ

  • เอฟเฟกต์สำหรับไอคอนที่กด / คลิกใช้เอฟเฟกต์ระลอกคลื่นวงกลมเช่น:

    <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@android:color/darker_gray" />

  • เอฟเฟกต์สำหรับมุมมองที่คลิกด้วยขอบเขตสี่เหลี่ยมผืนผ้าเราสามารถเพิ่มระลอกคลื่นที่มีอยู่ได้เช่นร้อง:

    <?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#000000"> <item android:drawable="@drawable/your_background_drawable"/> </ripple>


2

สำหรับทุกมุมมอง

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

แต่สำหรับ cardview ที่มีการใช้ระดับความสูง

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

สำหรับเอฟเฟกต์การคลิกแบบวงกลมในแถบเครื่องมือ

android:background="?android:attr/actionBarItemBackground"

นอกจากนี้คุณต้องตั้งค่า

 android:clickable="true"
 android:focusable="true"

0

การเพิ่มคำตอบของAndràsเล็กน้อย:

คุณสามารถใช้postDelayedเพื่อทำให้ฟิลเตอร์สีคงอยู่เป็นระยะเวลาสั้น ๆ เพื่อให้เห็นได้ชัดเจนยิ่งขึ้น:

        @Override
        public boolean onTouch(final View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    v.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
                    v.invalidate();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    v.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            v.getBackground().clearColorFilter();
                            v.invalidate();
                        }
                    }, 100L);
                    break;
                }
            }
            return false;
        }

คุณสามารถเปลี่ยนค่าของการหน่วงเวลา 100L เพื่อให้เหมาะกับความต้องการของคุณ


0

หากคุณใช้พื้นหลัง xml แทน IMG ให้ลบสิ่งนี้:

<item>
    <bitmap android:src="@drawable/YOURIMAGE"/>
</item>

จากคำตอบที่ 1 ที่ @Ljdawson ให้เรา


0

สร้างไฟล์ounce.xmlสำหรับภาพเคลื่อนไหว

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale
        android:duration="100"
        android:fromXScale="0.9"
        android:fromYScale="0.9"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0" />

</set>

เพิ่มบรรทัดนี้ในonClickเพื่อเริ่มต้น

แอนิเมชั่นสุดท้าย myAnim = AnimationUtils.loadAnimation (นี่คือ R.anim.bounce); button.startAnimation (myAnim);

คุณจะได้รับเอฟเฟกต์การหดตัวในการคลิกปุ่ม

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