วิธีจัดการปุ่มย้อนกลับในกล่องโต้ตอบ?


96

ฉันกำลังพัฒนาแอพพลิเคชั่นที่เมื่อกดปุ่มมันจะเปิดกล่องโต้ตอบพร้อมปุ่มตกลงและยกเลิก

มันทำงานได้ดี

เมื่อผู้ใช้กดปุ่มย้อนกลับฉันจะจัดการสิ่งนี้ดังนี้

public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if ((keyCode == KeyEvent.KEYCODE_BACK)) 
    {

    }
 return super.onKeyDown(keyCode, event);
}

แต่วิธีการข้างต้นไม่ได้เรียก. ฉันจะจัดการกับเรื่องนี้ได้อย่างไร?


1
คุณต้องการให้ผู้ใช้สามารถยกเลิกกล่องโต้ตอบได้หรือไม่? หรือส่วน onKeyDown ของคุณทำอะไร?
Krueger

@kiran :: ชัดเจนกว่านี้หน่อยได้ไหม ??
KMI

คำตอบ:


241
dialog.setOnKeyListener(new Dialog.OnKeyListener() {

            @Override
            public boolean onKey(DialogInterface arg0, int keyCode,
                    KeyEvent event) {
                // TODO Auto-generated method stub
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    finish();
                    dialog.dismiss();
                }
                return true;
            }
        });

8
ไม่จำเป็นต้องยกเลิกDialog; finish()ดูแลเรื่องนี้อยู่แล้ว นอกจากนี้วิธีการนี้น่าจะกลับมาfalseจับภาพเหตุการณ์สำคัญที่อื่นได้
slinden77

6
ฉันคิดว่าคำตอบของ alexc ด้านล่างเป็นทางเลือกที่ดีกว่า
Simon Forsberg

23
ฉันเพิ่ม&& event.getAction() == KeyEvent.ACTION_UPคำตอบแล้ว หากไม่มีบล็อกโค้ดจะดำเนินการสองครั้ง (คีย์ลงและคีย์ขึ้น) ในตัวอย่างนี้ไม่สำคัญนัก แต่สำหรับการดำเนินการอื่นที่ไม่ใช่การเสร็จสิ้น () อาจมีความสำคัญมาก
Udo Klimaschewski

1
@dmmh ถ้าคุณไม่โทรdialog.dismiss()จะทำให้หน่วยความจำรั่ว
Pedro Lobito

2
ฉันแน่ใจว่าคุณพูดถูก แต่ในกรณีนั้นfinish()และdialog.dismiss()ควรสลับไปมาในโค้ดด้านบน
slinden77

115

ดูเหมือนว่าคุณต้องการตั้งค่า OnCancelListener เมื่อคุณสร้าง Dialog ดูเหมือนว่า:

dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {         
    @Override
    public void onCancel(DialogInterface dialog) {
        //do whatever you want the back key to do
    }
});

7
นี่คือคำตอบที่ดีที่สุดแน่นอน สวยและเรียบง่าย ไม่จำเป็นต้องตรวจจับ KeyEvent สมบูรณ์แบบ.
LargeGlasses

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

5
@ user2520215 หากคุณไม่ต้องการให้ทริกเกอร์เมื่อผู้ใช้คลิกนอกกล่องโต้ตอบคุณควรตั้งค่า dialog.setCanceledOnTouchOutside (เท็จ) นี่คือคำตอบที่ดีกว่าแน่นอน
Alhassan Abdulkadir

ขอบคุณที่ชี้ให้เห็น นี่เป็นแนวทางที่ดีกว่าอย่างแน่นอน
user2520215

3
ดูเหมือนจะไม่ได้ผลหากใช้มุมมองแบบกำหนดเอง (เช่นไม่ได้สร้างไดอะล็อก แต่เพียงแค่สืบทอดจาก DialogFragment) ในขณะที่ตัวฟังคีย์ทำงานในกรณีนั้น
Julian Honma

19

คุณต้องลบล้างOnCancelวิธีการ วิธีนี้เรียกใช้การกดปุ่มย้อนกลับ นี่คือรหัสที่เหมาะกับฉัน

 AlertDialog alertDialog;

    alertDialog.setOnCancelListener(new OnCancelListener() 
    {                   
           @Override
            public void onCancel(DialogInterface dialog) 
             {
               // TODO Auto-generated method stub

                    dialog.dismiss();                           

            }
}); 

หวังว่านี่จะช่วยคุณและยอมรับหากเป็นประโยชน์กับคุณ

ขอบคุณ ..


7

ลองทำตามนี้

 new AlertDialog.Builder(this).setOnKeyListener(new DialogInterface.OnKeyListener() {

                        @Override
                        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {

                            if(keyCode == KeyEvent.KEYCODE_BACK){
                                Logger.d(TAG, "--------- Do Something -----------");
                                return true;
                            }
                            return false;


                        }
                    })

1
เหตุใดฉันจึงใช้ setOnCancelListener ใน Builder ไม่ได้
ffleandro

3

หากคุณใช้ DialogFragment จากสิ่งที่ฉันสามารถบอกได้ว่าวิธีที่ถูกต้องคือการแทนที่ onCancel ()

ฉันสังเกตว่าsetOnCancelListenerใช้งานไม่ได้และใช้setOnKeyListenerงานได้ แต่สำหรับฉันมีผลข้างเคียงที่สนุกที่มันกลืนทุกปุ่มหากกล่องโต้ตอบของคุณมีข้อความแก้ไข


1

เป็นเพราะเมื่อกล่องโต้ตอบของคุณเปิดขึ้นหน้าต่างของคุณจะเลื่อนโฟกัสไปที่กล่องโต้ตอบ ตอนนี้คุณต้องจัดการkeyกับ Dialog ของคุณ


แม้ว่าจะถูกต้อง แต่คำตอบนี้ไม่ได้ให้ข้อมูลมากนักเกี่ยวกับวิธีจัดการkeyในกล่องโต้ตอบ
Simon Forsberg

1

แทนที่วิธีการonBackPressed()ในกล่องโต้ตอบของคุณเองและใช้ในรหัสของคุณ:

public class MyDialog extends Dialog {

    public MyDialog(@NonNull Context context) {
        super(context);
    }

    @Override
    public void onBackPressed() {
        // Do what you want
    }
}

ใช้:

MyDialog dlg = new MyDialog(context);
dlg.show();

0

รหัสนี้ใช้งานได้:

    Dialog dlg = new Dialog(thisAct, R.style.DialogTheme);
    dlg.setContentView(view);
    dlg.setCancelable(false);
    dlg.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
    dlg.setOnKeyListener((arg0, keyCode, event) -> {
        Timber.d("onKey(%d)", keyCode);
        //{home intercepting
        if ((keyCode == KeyEvent.KEYCODE_HOME)) {
            Timber.i("HOME pressed");
            return true;
        }

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