Android - วิธีแทนที่ปุ่ม“ ย้อนกลับ” ดังนั้นมันจึงไม่เสร็จสิ้น () กิจกรรมของฉัน


199

ขณะนี้ฉันมีกิจกรรมที่เมื่อมันได้รับการแสดงการแจ้งเตือนจะได้รับการแสดงในแถบการแจ้งเตือน

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

ปัญหาเกิดขึ้นเมื่อผู้ใช้กดปุ่มย้อนกลับกิจกรรมของฉันถูกทำลาย แต่การแจ้งเตือนยังคงอยู่เนื่องจากฉันต้องการให้ผู้ใช้สามารถกดย้อนกลับ แต่ยังสามารถเข้าถึงกิจกรรมผ่านการแจ้งเตือนได้ แต่เมื่อ USER ลองสิ่งนี้ฉันจะได้รับ Null Pointers เนื่องจากเป็นการพยายามเริ่มกิจกรรมใหม่แทนที่จะนำสิ่งเก่ากลับมา

โดยพื้นฐานแล้วฉันต้องการให้ปุ่มย้อนกลับทำหน้าที่เหมือนกับปุ่มโฮมและนี่คือสิ่งที่ฉันได้ลองมาแล้ว:


        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event)  {
            if (Integer.parseInt(android.os.Build.VERSION.SDK) < 5
                    && keyCode == KeyEvent.KEYCODE_BACK
                    && event.getRepeatCount() == 0) {
                Log.d("CDA", "onKeyDown Called");
                onBackPressed();
            }

            return super.onKeyDown(keyCode, event);
        }

        public void onBackPressed() {
            Log.d("CDA", "onBackPressed Called");
            Intent setIntent = new Intent(Intent.ACTION_MAIN);
            setIntent.addCategory(Intent.CATEGORY_HOME);
            setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(setIntent); 

            return;
        }   

อย่างไรก็ตามรหัสข้างต้นยังคงอนุญาตให้กิจกรรมของฉันถูกทำลายฉันจะหยุดกิจกรรมของฉันจากการถูกทำลายได้อย่างไรเมื่อกดปุ่มย้อนกลับ?


มีคำถามที่คล้ายกัน: stackoverflow.com/questions/2459848/…
aleung

1
คำตอบที่คล้ายกัน .. stackoverflow.com/questions/5914040/…
Zar E Ahmer

นอกจากนี้ผมคิดว่าคุณต้องเปลี่ยนรหัสของคุณเพื่อ `ถ้า (Integer.parseInt (android.os.Build.VERSION.SDK)> 5 , the <` ควรจะเป็น>.
SudoPlz

1
แม้ว่าคุณจะแก้ปัญหานี้คุณยังต้องจัดการกับความเป็นไปได้ของระบบที่จะฆ่าแอปของคุณใช่ไหม ฉันหมายถึงกรณีที่เป็นโมฆะยังคงเป็นไปได้? หรือถ้าระบบฆ่าแอปของคุณไม่ว่าด้วยเหตุผลใดมันจะลบการแจ้งเตือนของคุณด้วยหรือไม่ ฉันคิดว่าสิ่งนี้จะต้องเป็นปัญหาเนื่องจากจุดประสงค์ของการแจ้งเตือนคือมีอยู่แม้ว่าแอปจะไม่มี
ToolmakerSteve

ตรวจสอบตัวอย่างรหัสสมัครที่นี่freakyjolly.com/how-to-add-back-arrow-in-android-activity
รหัส Spy

คำตอบ:


276

นำผู้ฟังที่สำคัญของคุณหรือกลับเมื่อคุณมีtrueKEY_BACK

คุณเพียงแค่ต้องการสิ่งต่อไปนี้เพื่อจับปุ่มย้อนกลับ (ตรวจสอบให้แน่ใจว่าไม่ได้โทรเข้าซูเปอร์อินonBackPressed())

นอกจากนี้หากคุณวางแผนที่จะให้บริการทำงานในพื้นหลังตรวจสอบstartForeground()ให้แน่ใจว่าได้รับการแจ้งเตือนอย่างต่อเนื่องมิฉะนั้น Android จะฆ่าบริการของคุณหากจำเป็นต้องเพิ่มหน่วยความจำ

@Override
public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);
}

70

มันง่ายกว่าที่จะใช้มันด้วยโค้ดเพียงบรรทัดเดียว:

@Override
public void onBackPressed() {
   moveTaskToBack(true);
}

นี่ควรเป็นคำตอบที่ยอมรับได้ นี่เป็นคำถามที่ถามและใช้ฟังก์ชั่นคลีนในตัว
Shadoninja

ขอบคุณ :) คุณช่วยอธิบายแนวคิดเบื้องหลังได้ไหม?
Farrukh Faizy

1
คุณเพียงแค่แทนที่เหตุการณ์ onBackPressed () ทำให้กิจกรรมนั้นย้ายไปด้านหลัง
Squirrelkiller

1
โซลูชันนี้จะไม่นำกิจกรรมกลับมาเมื่อคุณเรียกใช้แอปจากหน้าจอหลักอีกครั้ง (หากมีกิจกรรมอื่นในกองงาน)
IgorGanapolsky

12

ฉันคิดว่าสิ่งที่คุณต้องการคือไม่แทนที่ปุ่มย้อนกลับ (ที่ดูเหมือนจะไม่เป็นความคิดที่ดี - ระบบปฏิบัติการ Android กำหนดพฤติกรรมนั้นทำไมต้องเปลี่ยน?) แต่ใช้Activity Lifecycleและยืนยันการตั้งค่า / ข้อมูลของคุณในonSaveInstanceState (Bundle)เหตุการณ์

@Override
onSaveInstanceState(Bundle frozenState) {
    frozenState.putSerializable("object_key",
        someSerializableClassYouWantToPersist);
    // etc. until you have everything important stored in the bundle
}

จากนั้นคุณใช้onCreate (Bundle)เพื่อดึงทุกอย่างออกจากBundleที่ยังคงอยู่และสร้างสถานะของคุณใหม่

@Override
onCreate(Bundle savedInstanceState) {
    if(savedInstanceState!=null){ //It could be null if starting the app.
        mCustomObject = savedInstanceState.getSerializable("object_key");
    }
    // etc. until you have reloaded everything you stored
}

พิจารณารหัส psuedo ด้านบนเพื่อชี้คุณในทิศทางที่ถูกต้อง การอ่านเกี่ยวกับวงจรชีวิตของกิจกรรมควรช่วยให้คุณกำหนดวิธีที่ดีที่สุดในการบรรลุสิ่งที่คุณต้องการ


สวัสดี Kiswa นี่เป็นเรื่องจริงฉันไม่ต้องการเปลี่ยนพฤติกรรมเริ่มต้น ฉันได้ลองใช้ onSavedInstanceState แล้ว แต่มันไม่ทำงาน แต่ฉันเชื่อว่าฉันพบข้อผิดพลาดแล้ว ขอบคุณ
Donal Rafferty

5
ฉันเจอสถานการณ์อย่างน้อยสองสามอย่างที่ฉันต้องการจำลองพฤติกรรมสแต็กกิจกรรมมาตรฐานโดยไม่ต้องเริ่มกิจกรรมใหม่ ในกรณีเหล่านี้ฉันคิดว่ามันเหมาะสมที่จะแทนที่ค่าเริ่มต้น onBackPressed () พฤติกรรม โดยทั่วไปแล้วฉันยอมรับ: หลีกเลี่ยงการเอาชนะ
Matt Briançon

4
ฉันเห็นด้วยกับ @Matt ฉันกำลังทำงานกับเกมข้ามแพลตฟอร์มที่ใช้ NDK ดังนั้นมันง่ายที่สุดถ้าทุกอย่างเป็นกิจกรรมเดียว ด้วยเหตุนี้พฤติกรรมเริ่มต้นของปุ่มย้อนกลับคือการหลบหนีแอปพลิเคชันซึ่งไม่ใช่สิ่งที่ผู้ใช้คาดหวัง ดังนั้นฉันจึงต้องเขียนทับพฤติกรรมเริ่มต้นเพื่อให้กิจกรรมทำงานแตกต่างกันราวกับว่าผู้ใช้ไปทำกิจกรรมที่แตกต่างกันจริงและออกจากแอปในบางสถานการณ์เท่านั้น
Leif Andersen

1
ไม่ใช่ onSaveInstanceState และการบันทึกข้อมูลเป็นคำถามที่แตกต่างอย่างสิ้นเชิงหรือไม่
Ted

@Ted - หากคุณบอกว่าใน adition ไปที่ onSaveInstanceState จะต้องมีรหัสที่ยังคงมีข้อมูลแอปที่ไม่ใช่ UI แล้วฉันก็เห็นด้วย ทันทีที่คุณละทิ้งพื้นหน้าแอปของคุณอาจถูกฆ่าโดยไม่มีการเตือนเพิ่มเติม ต้องบันทึกทุกสิ่งที่สำคัญ ในทางกลับกันฉันคิดว่าวิธีการวงจรชีวิตของแอพจะถูกเรียกโดยไม่คำนึงถึงเทคนิคที่คุณใช้ในการซ่อนแอพ แต่เก็บไว้รอบ ๆ ดังนั้นจึงไม่จำเป็นต้องเพิ่มตรรกะการบันทึกสำหรับกรณีนี้ แอปของคุณต้องการรหัสนั้นในที่ที่เหมาะสมโดยไม่คำนึงถึง
ToolmakerSteve

11

ทำอย่างนี้ ..

@Override
public void onBackPressed() {
    //super.onBackPressed();
}

แสดงความคิดเห็นออก //super.onBackPressed (); จะทำเคล็ดลับ


1
การสังเกตที่มีประโยชน์ แต่สิ่งนี้จะไม่ทำให้ปุ่มย้อนกลับไม่ทำอะไรเลยราวกับว่ามันหัก นั่นไม่ใช่สิ่งที่ดีที่ต้องทำ - สร้างความสับสนและสร้างความรำคาญให้กับผู้ใช้ IMHO จะต้องเพิ่มตรรกะจากคำตอบอื่นเพื่อให้ทำหน้าที่เหมือนปุ่มโฮมตามที่ร้องขอ คำตอบที่ได้รับการยอมรับกล่าวถึงว่าพวกเขาตั้งใจที่จะไม่เรียกใช้วิธีการพิเศษ
ToolmakerSteve

ใช่คุณพูดถูก มันจะแทนที่ปุ่มย้อนกลับและจะไม่ทำอะไรจนกว่าคุณจะใส่ตรรกะที่นั่น อาจเป็นเงื่อนไขสำหรับการกดสองครั้งที่ปุ่มเพื่อปิดแอปพลิเคชันหรือคุณเพียงแค่ต้องการปิดการใช้งานการดำเนินงานอย่างต่อเนื่อง (กล่องโต้ตอบความคืบหน้า) ฯลฯ แต่สมบูรณ์ตามข้อกำหนด
androCoder-BD


3

ในกรณีที่คุณต้องการจัดการกับพฤติกรรมของปุ่มย้อนกลับ (ที่ด้านล่างของโทรศัพท์) และปุ่มโฮม (หนึ่งทางด้านซ้ายของแถบการกระทำ) กิจกรรมที่กำหนดเองนี้ที่ฉันใช้ในโครงการของฉันอาจช่วยคุณได้ .

import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;

/**
 * Activity where the home action bar button behaves like back by default
 */
public class BackActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupHomeButton();
    }

    private void setupHomeButton() {
        final ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeButtonEnabled(true);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                onMenuHomePressed();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    protected void onMenuHomePressed() {
        onBackPressed();
    }
}

ตัวอย่างการใช้งานในกิจกรรมของคุณ:

public class SomeActivity extends BackActivity {

    // ....

    @Override
    public void onBackPressed()
    {
        // Example of logic
        if ( yourConditionToOverride ) {
            // ... do your logic ...
        } else {
            super.onBackPressed();
        }
    }    
}

1
@Override
public void onBackPressed() {
// Put your code here.
}

//I had to go back to the dashboard. Hence,

@Override
public void onBackPressed() {
    Intent intent = new Intent(this,Dashboard.class);
    startActivity(intent);
}
Just write this above or below the onCreate Method(within the class)

0

ใน Kotlin:

val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
    // Handle the back button event
}

สำหรับข้อมูลเพิ่มเติมคุณสามารถตรวจสอบนี้

มีคำถามเฉพาะเกี่ยวกับการเอาชนะปุ่มย้อนกลับใน Kotlin

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