Bagaimana saya bisa kembali ke aktivitas orang tua dengan benar?


179

Saya memiliki 2 aktivitas (A dan B) di aplikasi android saya dan saya menggunakan maksud untuk beralih dari aktivitas A ke aktivitas B. Penggunaan parent_activity diaktifkan:

 <activity
        android:name=".B"
        android:label="B" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
  </activity>

Saya juga menggunakan tema yang menyediakan tombol-UP.

Jadi setelah saya menelepon aktivitas BI dapat menggunakan tombol-UP untuk kembali ke aktivitas A. Masalahnya adalah aplikasi tersebut sepertinya memanggil onCreate () -fungsi dari aktivitas A lagi dan ini bukan perilaku yang saya butuhkan. Saya membutuhkan aktivitas A agar terlihat sama seperti sebelum saya menelepon aktivitas B.

Apakah ada cara untuk mencapai ini?

Terima kasih sebelumnya

EDIT:

Saya tidak menulis kode apa pun untuk memulai aktivitas B dari aktivitas A. Saya pikir ini dibuat otomatis oleh gerhana.

Kelas B terlihat seperti:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_b, menu);
    return true;
}


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

Posting kode Anda, untuk memulai Kegiatan A dari B ..
user370305

Jika saya mengerti Anda benar, Anda dapat menggunakan startActivityForResult () dan mengembalikan resultCode atau sesuatu.
Law Gimenez

Harap perbarui jawaban yang benar yang ditandai ini! Jawaban yang BENAR berasal dari LorenzCK - bukan dari pengguna ......! Memberi tag ini sebagai benar menyesatkan dan membuat lebih banyak programmer salah paham navigasi dibandingkan dengan navigasi belakang!
Zordid

Wah, banyak sekali jawaban yang salah di sini, bisakah Anda membantu membersihkan ini ...?
Zordid

@ashiaka - Jawaban yang benar sesuai desain kode Anda diperbarui.
user370305

Jawaban:


334

Anda mendeklarasikan aktivitas A dengan standar launchModedi manifes Android. Menurut dokumentasi , itu berarti yang berikut:

Sistem selalu membuat instance baru dari aktivitas dalam tugas target dan mengarahkan maksudnya.

Oleh karena itu, sistem dipaksa untuk membuat kembali aktivitas A (yaitu panggilan onCreate) bahkan jika tumpukan tugas ditangani dengan benar.

Untuk memperbaiki masalah ini, Anda perlu mengubah manifes, menambahkan atribut berikut ke deklarasi aktivitas A:

android:launchMode="singleTop"

Catatan: menelepon finish()(seperti yang disarankan sebagai solusi sebelumnya) hanya berfungsi bila Anda benar - benar yakin bahwa aktivitas B misalnya Anda mengakhiri hidup di atas instance aktivitas A. Dalam alur kerja yang lebih kompleks (misalnya, meluncurkan aktivitas B dari pemberitahuan) ini mungkin tidak terjadi dan Anda harus benar memulai aktivitas A dari B.


11
Berikut adalah penjelasan dari dokumen Android, Mode "standar" dan "singleTop" berbeda satu sama lain hanya dalam satu hal: Setiap kali ada niat baru untuk aktivitas "standar", instance baru kelas dibuat untuk merespons niat itu. Setiap instance menangani satu niat. Demikian pula, contoh baru dari aktivitas "singleTop" juga dapat dibuat untuk menangani maksud baru. Namun, jika tugas target sudah memiliki instance aktivitas yang ada di bagian atas stacknya, instance tersebut akan menerima maksud baru (dalam panggilan onNewIntent ()); contoh baru tidak dibuat.
kpsfoo

Perhatikan bahwa menurut dokumentasi navigateUpFromSameTask(...) harus ditambahkan FLAG_ACTIVITY_CLEAR_TOPke upIntent(melalui navigateUpTo(...)yang harus menghasilkan perilaku yang sama (sesuai dengan panduan ini ), tetapi bendera tidak pernah ditetapkan - dan karena itu jawaban ini masuk akal
Anigif

82

Jawaban Diperbarui: Desain Navigasi Atas

Anda harus mendeklarasikan aktivitas mana yang merupakan induk yang tepat untuk setiap aktivitas. Melakukannya memungkinkan sistem untuk memfasilitasi pola navigasi seperti Naik karena sistem dapat menentukan aktivitas induk logis dari file manifes.

Jadi untuk itu Anda harus mendeklarasikan Aktivitas induk Anda di tag Activity dengan atribut

android:parentActivityName

Suka,

<!-- The main/home activity (it has no parent activity) -->
    <activity
        android:name="com.example.app_name.A" ...>
        ...
    </activity>
    <!-- A child of the main activity -->
    <activity
        android:name=".B"
        android:label="B"
        android:parentActivityName="com.example.app_name.A" >
        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
    </activity>

Dengan aktivitas induk yang dideklarasikan dengan cara ini, Anda dapat menavigasi ke induk yang sesuai seperti di bawah ini,

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Respond to the action bar's Up/Home button
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Jadi, ketika Anda memanggil NavUtils.navigateUpFromSameTask(this);metode ini, ia menyelesaikan aktivitas saat ini dan memulai (atau melanjutkan) aktivitas induk yang sesuai. Jika aktivitas induk target ada di tumpukan belakang tugas, itu diajukan seperti yang didefinisikan oleh FLAG_ACTIVITY_CLEAR_TOP.

Dan untuk menampilkan tombol Atas Anda harus mendeklarasikan setDisplayHomeAsUpEnabled():

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

Jawaban Lama: (Tanpa Navigasi Naik, Navigasi Kembali bawaan)

Itu terjadi hanya jika Anda memulai kembali Kegiatan A dari Kegiatan B.

Menggunakan startActivity().

Alih-alih dari Aktivitas A, mulai Kegiatan B menggunakan startActivityForResult()dan menimpa onActivtyResult()di Aktivitas A.

Sekarang di Aktivitas B cukup panggil finish()tombol Naik. Jadi sekarang Anda diarahkan ke Activity A onActivityResult()tanpa membuat Activity A lagi ..


Saya tidak tahu di mana startActivity () dalam aktivitas B disebut. Saya telah memposting kode sumber aktivitas B ...
ashiaka

18
Alih-alih NavUtils.navigateUpFromSameTask(this); menulis baris kode finish().
user370305

4
Itu menimbulkan pertanyaan, mengapa Google tidak menyebutkan apa-apa tentang finish()atau startActivityForResult()dalam dokumentasi mereka tentang Navigasi ( developer.android.com/design/patterns/navigation.html )?
wired00

ini terdengar seperti solusi yang melelahkan. @LorenzCK sepertinya jauh lebih baik.
carmen_munich

Terima kasih banyak telah menggunakan NavUtils.navigateUpFromSameTask (ini). Besar plus! Saya telah mencari metode seperti ini untuk mengganti selesai () yang tidak kembali ke aktivitas induk dalam beberapa keadaan. finish () pada dasarnya akan kembali ke aktivitas sebelumnya yang tidak harus aktivitas induk.
Hong

22

Saya memiliki pengaturan yang hampir sama yang mengarah ke perilaku yang tidak diinginkan yang sama. Bagi saya ini berhasil: menambahkan atribut berikut ke aktivitas A di Manifest.xmlaplikasi saya:

android:launchMode="singleTask"

Lihat artikel ini untuk penjelasan lebih lanjut.


1
Dari sudut pandang saya solusi yang tepat untuk masalah tersebut. Ini akan berperilaku seperti jika Anda memanggil selesai () jika Kegiatan ada di tumpukan tugas. Jika tidak, ini akan dibuat dan dimulai.
Johan

5
Ini bukan cara yang benar karena akan membuat tugas baru yang tidak perlu setiap kali, Anda harus menggunakan launchMode = "singleTop".
kpsfoo

19

Meskipun merupakan pertanyaan lama, inilah solusi (imho yang terbersih dan terbaik) yang lain karena semua jawaban sebelumnya tidak berhasil bagi saya karena saya mendalami Aktivitas B dari Widget .

public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
    Log.v(logTag, "Recreate back stack");
        TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
  } else {
    NavUtils.navigateUpTo(this, upIntent);
  }
}

[ https://stackoverflow.com/a/31350642/570168 ]

Tetapi juga lihat: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android


7

Cara yang lebih baik untuk mencapai ini adalah dengan menggunakan dua hal: panggilan:

NavUtils.navigateUpFromSameTask(this);

Sekarang, agar ini berfungsi, Anda harus memiliki file manifes Anda menyatakan bahwa aktivitas A memiliki aktivitas induk B. Aktivitas induk tidak memerlukan apa-apa. Di versi 4 dan di atas Anda akan mendapatkan panah kembali yang bagus tanpa upaya tambahan (ini dapat dilakukan pada versi yang lebih rendah juga dengan sedikit kode, saya akan meletakkannya di bawah) Anda dapat mengatur data ini di tab aplikasi manifest-> di GUI (gulir ke bawah ke nama aktivitas induk, dan letakkan dengan tangan)

Node pendukung:

jika Anda ingin mendukung versi di bawah versi 4, Anda harus memasukkan metadata juga. klik kanan pada aktivitas, tambahkan-> meta data, nama = android.support.PARENT_ACTIVITY dan nilai = your.full.activity.name

untuk mendapatkan panah yang bagus di versi yang lebih rendah juga:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

harap dicatat Anda akan membutuhkan dukungan perpustakaan versi 7 untuk membuat semua ini berfungsi, tetapi itu sangat berharga!


5

Apa yang berhasil bagi saya adalah menambahkan:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onBackPressed() {
        finish();
    }

ke TheRelevantActivity.javadan sekarang berfungsi seperti yang diharapkan

dan ya jangan lupa menambahkan:

getSupportActionbar.setDisplayHomeAsUpEnabled(true);dalam onCreate()metode


4

Saya mencoba android:launchMode="singleTask", tetapi itu tidak membantu. Bekerja untuk saya gunakanandroid:launchMode="singleInstance"


Menambahkan android: launchMode = "singleInstance" ke aktivitas induk menyelesaikan masalah untuk saya
emir

4

Menambah jawaban @ LorenCK, ubah

NavUtils.navigateUpFromSameTask(this);

ke kode di bawah ini jika aktivitas Anda dapat dimulai dari aktivitas lain dan ini dapat menjadi bagian dari tugas yang dimulai oleh beberapa aplikasi lain

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    TaskStackBuilder.create(this)
            .addNextIntentWithParentStack(upIntent)
            .startActivities();
} else {
    NavUtils.navigateUpTo(this, upIntent);
}

Ini akan memulai tugas baru dan memulai Aktivitas induk Aktivitas Anda yang dapat Anda tetapkan dalam Manifest seperti di bawah ini dari versi Min SDK <= 15

<meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.app_name.A" />

Atau menggunakan parentActivityNamejika> 15


Catatan: Apakah menyatakan parentActivityNameuntuk SDK> 15 atau yang lain itu akan memberi Anda beberapa crash acak
Sourabh

3

Saya memiliki masalah serupa menggunakan Android 5.0 dengan nama aktivitas orang tua yang buruk

<activity
        android:name=".DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName=".MainActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>

Saya menghapus com.example.myfirstapp dari nama aktivitas induk dan itu berfungsi dengan baik


2

Tambahkan ke informasi manifes aktivitas Anda dengan atribut

android:launchMode="singleTask"

bekerja dengan baik untuk saya


1
Alur yang lengkap adalah seperti @Override public boolean onOptionsItemSelected (item MenuItem) {switch (item.getItemId ()) {case android.R.id.home: NavUtils.navigateUpFromSameTask (this); kembali benar; } kembalikan super.onOptionsItemSelected (item); }
Pravesh Kumar

Tambahkan ke manifes <aktivitas android Anda: name = ". MainActivity" android: label = "@ string / title_activity_main"> </activity> <activity android: name = ". CreateEventActivity" android: label = "@ string / title_activity_create_event" android : launchMode = "singleTask" android: parentActivityName = ". MainActivity"> <meta-data android: name = "android.support.PARENT_ACTIVITY" android: value = ". MainActivity" /> </activity>
Pravesh Kumar

2

Di kelas Java: -

    toolbar = (Toolbar) findViewById(R.id.apptool_bar);
    setSupportActionBar(toolbar);

    getSupportActionBar().setTitle("Snapdeal");

    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

Dalam Manifes: -

<activity
            android:name=".SubActivity"
            android:label="@string/title_activity_sub"
            android:theme="@style/AppTheme" >
            <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"></meta-data>
    </activity>

Itu akan membantumu


1
    @Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
    case android.R.id.home:
        finish();
        return true;
}
return super.onOptionsItemSelected(item);

seperti tekan Kembali


1

coba ini:

Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
    intent = getIntent();   
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_b, menu);
    return true;
}  

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

0

Pergi ke manifes saya dan menambahkan android:launchMode="singleTop" aktivitas tersebut membantu saya.

Ini secara khusus menyelesaikan masalah saya karena saya tidak ingin Android membuat contoh baru dari aktivitas sebelumnya setelah memukul Up tombol di toolbar - Saya malah ingin menggunakan instance yang ada dari aktivitas sebelumnya ketika saya naik hierarki navigasi.

Referensi: android: launchMode


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.