Bir üst etkinliğe nasıl doğru bir şekilde dönebilirim?


179

Android uygulamamda 2 aktivite (A ve B) var ve A aktivitesinden B aktivitesine ulaşmak için bir niyet kullanıyorum. Parent_activity kullanımı etkin:

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

UP düğmesi sağlayan bir tema da kullanıyorum.

Bu yüzden faaliyet BI çağırdıktan sonra A faaliyetine geri almak için UP-düğmesini kullanabilirsiniz. Sorun, uygulamanın tekrar etkinlik A'nın onCreate () işlevini çağırmak gibi görünüyor ve bu ihtiyacım olan davranış değildir. Etkinlik B'yi aramadan önce göründüğü gibi görünmek için A etkinliğine ihtiyacım var.

bunu arşivlemenin bir yolu var mı?

Şimdiden teşekkürler

DÜZENLE:

B aktivitesini A aktivitesinden başlatmak için herhangi bir kod yazmadım. Eclipse tarafından otomatik olarak üretildiğini düşünüyorum.

B Sınıfı şöyle görünür:

    @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);
}

Etkinlik A'yı B'den başlatmak için size kod
gönderin

Seni doğru anlarsam, startActivityForResult () öğesini kullanabilir ve bir sonuçKodu veya başka bir şey döndürebilirsiniz.
Gimenez

Lütfen etiketli doğru cevabınızı güncelleyin! DOĞRU cevap LorenzCK geliyor - kullanıcıdan değil ......! Bunu doğru olarak etiketlemek yanıltıcıdır ve daha fazla programcının navigasyonu ters navigasyon yerine yanlış anladığını gösterir!
Zordid

Gee, burada çok fazla yanlış cevap var, lütfen bunu temizlemeye yardım eder misin ...?
Zordid

@ashiaka - Kod tasarımınıza göre doğru cevap güncellenir.
user370305

Yanıtlar:


334

launchModeAndroid bildirimindeki standartla A etkinliği bildirdiniz . Belgelere göre , bu şu anlama gelir:

Sistem her zaman hedef görevde etkinliğin yeni bir örneğini oluşturur ve amacı buna yönlendirir.

Bu nedenle, onCreategörev yığını doğru işlenmiş olsa bile sistem A etkinliğini (yani çağırmak ) yeniden oluşturmak zorunda kalır .

Bu sorunu gidermek için, bildirimi değiştirmeniz ve A etkinlik bildirimine aşağıdaki özniteliği eklemeniz gerekir:

android:launchMode="singleTop"

Not: çağırmadan finish()(önce çözüm olarak önerdiği gibi) çalışır ancak siz hazır olduğunuzda tamamen emin olduğu etkinlik B örneği size (bir bildirimden aktivite B başlatılması, örneğin) daha karmaşık iş akışlarında aktivite A. örneğine üstünde hayatlarını sona erdirici durum böyle olmayabilir ve A aktivitesini B'den doğru bir şekilde başlatmanız gerekir.


11
İşte Android belgelerinden açıklama, "Standart" ve "singleTop" modları birbirinden yalnızca bir açıdan farklıdır: "Standart" bir etkinlik için her yeni bir niyet olduğunda, yanıt vermek için sınıfın yeni bir örneği oluşturulur bu niyet. Her örnek tek bir amacı ele alır. Benzer şekilde, yeni bir amacı işlemek için yeni bir "singleTop" etkinliği örneği de oluşturulabilir. Ancak, hedef görev zaten yığının üstünde etkinliğin mevcut bir örneğine sahipse, bu örnek yeni amacı (bir onNewIntent () çağrısında) alır; yeni bir örnek oluşturulmaz.
kpsfoo

Not göre bu belgelere navigateUpFromSameTask(...) eklenmesi olmalıdır FLAG_ACTIVITY_CLEAR_TOPiçin upIntent(aracılığıyla navigateUpTo(...)hangi (göre aynı davranışa yol açmalıdır Bu kılavuzda ), ancak bayrak set asla - ve bu nedenle bu cevap mantıklı
anigif

82

Güncel Cevap: Yukarı Navigasyon Tasarımı

Her bir etkinlik için hangi etkinliğin uygun ebeveyn olduğunu bildirmeniz gerekir. Bu, sistemin manifest dosyasından mantıksal üst etkinliği belirleyebilmesi nedeniyle, sistemin Yukarı gibi gezinme düzenlerini kolaylaştırmasına olanak tanır.

Bu nedenle, üstteki Etkinliğinizi, Etkinlik etiketinde özellikli olarak bildirmeniz gerekir

android:parentActivityName

Sevmek,

<!-- 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>

Üst etkinlik bu şekilde bildirildiğinde, aşağıdaki gibi uygun üst öğeye gidebilirsiniz,

@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);
}

NavUtils.navigateUpFromSameTask(this);Bu yöntemi çağırdığınızda , geçerli etkinliği bitirir ve uygun üst etkinliği başlatır (veya devam ettirir). Hedef üst etkinlik görevin arka yığınındaysa, tarafından tanımlandığı şekilde ileri getirilir FLAG_ACTIVITY_CLEAR_TOP.

Ve Yukarı düğmesini görüntülemek için setDisplayHomeAsUpEnabled():

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

Eski Cevap: (Yukarı Gezinme Olmadan, varsayılan Geri Gezinme)

Yalnızca A Aktivitesini tekrar B Aktivitesinden başlatırsanız olur.

Kullanma startActivity().

Bunun yerine Etkinlik A'dan Etkinlik B'yi kullanarak Etkinlik A'yı kullanın startActivityForResult()ve geçersiz kılın onActivtyResult().

Şimdi Etkinlik B'de sadece finish()Yukarı düğmesine basın. Şimdi A onActivityResult()Aktivitesini tekrar A Aktivitesi yaratmadan yönlendirdiniz .


B aktivitesinde startActivity () işlevinin nerede çağrıldığını bilmiyorum. Ben B aktivitesinin kaynak kodunu gönderdim ...
ashiaka

18
Kod satırı NavUtils.navigateUpFromSameTask(this); yazmak yerine finish().
user370305

4
Bu soruyu, Google'ın nasıl hakkında bir şey söz etmez gelmek yalvarır finish()veya startActivityForResult()Navigasyon (kendi belgelerinde developer.android.com/design/patterns/navigation.html )?
wired00

bu zahmetli bir çözüm gibi geliyor. @LorenzCK yanıtı çok daha iyi görünüyor.
carmen_munich

NavUtils.navigateUpFromSameTask (this) ürününü kullandığınız için çok teşekkür ederiz. Büyük artı! Bazı durumlarda üst etkinliğe dönmeyen finish () yerine böyle bir yöntem arıyordum. finish () aslında ana etkinlik olması gerekmeyen önceki etkinliğe geri döner.
Hong

22

Hemen hemen aynı kurulumla aynı istenmeyen davranışa neden oldum. Benim için bu çalıştı: Manifest.xmlUygulamamın A etkinliğine aşağıdaki özelliği eklemek :

android:launchMode="singleTask"

Daha fazla açıklama için bu makaleye bakın .


1
Benim bakış açımdan soruna doğru çözüm. Bu işlem, görev yığınında Etkinlik varsa, finish () adını vermiş gibi davranacaktır. Bu durumda oluşturulacak ve başlatılacaktır.
Johan

5
Bu, her seferinde gereksiz yere yeni bir görev oluşturacağından doğru bir yol değildir, bunun yerine launchMode = "singleTop" öğesini kullanmalısınız.
kpsfoo

19

Eski bir soruya da, burada beri tüm önceki answeres olarak çözüm benim için iş vermedi (en temiz ve en iyi IMHO) başka bir şeydir Etkinlik B deeplinked bir mesafede 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 ]

Ayrıca bakınız: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android


7

Bunu başarmanın daha iyi bir yolu iki şey kullanmaktır:

NavUtils.navigateUpFromSameTask(this);

Şimdi, bunun çalışması için, manifest dosyanızın A aktivitesinin B üst aktivitesine sahip olduğunu belirtmeniz gerekir. Üst aktivitenin hiçbir şeye ihtiyacı yoktur. Sürüm 4 ve üzeri ek çaba harcamadan güzel bir geri ok alacaksınız (bu, daha düşük sürümlerde de küçük bir kodla yapılabilir, aşağıya koyacağım) Bu verileri manifest-> application sekmesinde ayarlayabilirsiniz. GUI'de (ana etkinlik adına ilerleyin ve elle koyun)

Destek düğümü:

sürüm 4'ün altındaki sürümü desteklemek istiyorsanız, meta verileri de eklemeniz gerekir. etkinliğe sağ tıklayın, add-> meta veri, ad = android.support.PARENT_ACTIVITY ve değer = your.full.activity.name

alt sürümlerde de güzel oku elde etmek için:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

Tüm bunların çalışması için destek kitaplığı sürüm 7'ye ihtiyacınız olacağını lütfen unutmayın, ama buna değer!


5

Benim için işe yarayan şey şunları ekliyordu:

    @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();
    }

için TheRelevantActivity.javabeklendiği gibi ve şimdi çalışıyor

ve evet eklemeyi unutmayın:

getSupportActionbar.setDisplayHomeAsUpEnabled(true);içinde onCreate()yöntemi


4

Denedim android:launchMode="singleTask", ama yardımcı olmadı. Benim için çalıştımandroid:launchMode="singleInstance"


Ebeveyn etkinliğine android: launchMode = "singleInstance" eklenmesi benim için sorunu çözdü
emir

4

@ LorenCK'nin cevabına ekleme, değiştirme

NavUtils.navigateUpFromSameTask(this);

etkinliğiniz başka bir etkinlikten başlatılabiliyorsa ve bu başka bir uygulama tarafından başlatılan görevin bir parçası olabilirse aşağıdaki koda

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

Bu, yeni bir görev başlatacak ve Min SDK sürümü <= 15 gibi Manifest'te tanımlayabileceğiniz Faaliyetinizin üst Etkinliğini başlatacaktır.

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

Veya parentActivityName> 15


Not: parentActivityNameSDK> 15 için beyanda bulunmayın, aksi takdirde size bazı rastgele çökmeler olur
Sourabh

3

Kötü bir ebeveyn etkinliği adı ile android 5.0 kullanırken benzer bir sorun yaşadım

<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>

Üst etkinlik adından com.example.myfirstapp öğesini kaldırdım ve düzgün çalıştı


3

Java sınıfında: -

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

    getSupportActionBar().setTitle("Snapdeal");

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

Manifest'te: -

<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>

Sana yardımcı olacak


2

Etkinlik bildirim bilgilerinize özellik ile ekleyin

android:launchMode="singleTask"

benim için iyi çalışıyor


1
Tam akış şuna benzer @OptionsItemSelected (MenuItem öğesi) {switch (item.getItemId ()) {case android.R.id.home: NavUtils.navigateUpFromSameTask (this); geri dönüş; } return super.onOptionsItemSelected (item); }
Pravesh Kumar

Manifestinize ekleyin <android android: 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-veri android: name = "android.support.PARENT_ACTIVITY" android: değer = ". MainActivity" /> </activity>
Pravesh Kumar

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);

Back press gibi


1

bunu dene:

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

Manifestime android:launchMode="singleTop"girmek ve aktiviteye eklemek benim için hile yaptı.

Bu, özellikle sorunumu çözdü çünkü Android'in Uparaç çubuğundaki düğmeye bastıktan sonra önceki etkinliğin yeni bir örneğini oluşturmasını istemiyordum - bunun yerine navigasyon hiyerarşisine gittiğimde önceki etkinliğin mevcut örneğini kullanmak istedim.

Referans: android: launchMode


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.