2012-08-23 7 views
7

sto usando questo codice per saltare indietro nel stack di attività (principalmente per passare a casa Attività):Come tag attività

Intent goTo = new Intent(this, HomeActivity.class); 
goTo.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(goTo); 


Quindi io creo nuovi intenti e impostare "target" per HomeActivity che è nello stack Attività in modo che tutta la pila venga cancellata da cima a questa HomeAttività.
Ora ho bisogno di un caso d'uso leggermente diverso. Ho per esempio cinque attività A-B-C-D-E (A iniziate B, ecc.) In pila. Ora ho bisogno di saltare da E a C o B a seconda di ciò che l'utente sceglie. Il problema è che le attività A, B, C, D, E hanno la stessa classe. Quindi non posso usare l'esempio sopra perché non so come indirizzare quell'Attività.
Quindi la domanda è se c'è un modo come "tagare l'attività" o manipolare con lo stack.
Grazie!

+0

se A ed E sono uguali, invece di chiamare E perché non si chiama l'attività A dalla cronologia? – Ishtiaq

+0

Ho modificato la mia domanda per renderla più chiara. Tutte le attività hanno la stessa classe. – Warlock

+0

Non capisco il tuo problema. Per favore dimmi, cosa c'è di male? –

risposta

0

La migliore e la soluzione più semplice (finora) saranno utilizzati frammenti e FragmentManager. Quindi tagga ciascun frammento e usa FragmentManager. Usare solo Activity può essere molto difficile avere quasi lo stesso risultato.

+0

Ho menzionato questo nella mia risposta! :) – Joe

+0

Il tuo approccio è molto diverso. Ma grazie per questa idea! ;-) – Warlock

1

Si può solo mantenere una condizione nella vostra dichiarazione se l'utente sceglie questo articolo passare intento di classe B e se l'utente sceglie che l'articolo passare intento di classe C

+0

Il problema è che tutte le attività hanno la stessa classe. – Warlock

1

Aggiungi extra al vostro intento che punterà l'attività Cosa fare. Per esempio

intent.putExtra("STATE", 1); 

E ottenere questo valore nel onCreate della vostra attività.

getIntent().getExtras() 
+0

Imho l'unico modo di usare questo approache è combinarlo con startActivityForResult/onActivityResult ecc. Ma speravo che ci fosse un modo forse più semplice per farlo. Posso avere dieci attività come menzionato sopra così suActivityResult verrà chiamato più volte ... – Warlock

+0

Se il problema principale è la stessa classe per tutte le attività, la soluzione potrebbe essere semplice. Crea una classe base, quindi estendila tutte le volte che vuoi e crea istanze di classi diverse. Ma penso che sia un approccio strano. Meglio fare una semplice macchina a stati e non riavviare la stessa attività 100 volte ... – Dimanoid

2

Non ho provato io stesso, ma penso che la soluzione migliore sarebbe quella di refactoring la vostra applicazione per utilizzare una pila di Fragment s all'interno di un singolo Activity (perché si può quindi gestire più facilmente la backstack utilizzando il fornito i metodi addToBackStack() e popBackStack()). Fondamentalmente ciò comporta lo spostamento della maggior parte del codice nella tua attività in un frammento e l'aggiunta del codice di manipolazione del backstack nell'attività). Puoi vedere il codice per FragmentBreadCrumbs (con API 11+) o il codice per HanselAndGretel (da usare con la libreria di compatibilità) per vedere come questo può essere implementato.

Tuttavia, se si desidera continuare a utilizzare il proprio attuale approccio multi-attività, quanto segue è un codice che ho trovato per illustrare come è possibile farlo.

Innanzitutto, aggiungi diverse classi interne per creare alias l'attività corrente e inserisci queste classi in un elenco di sequenze (osserva anche il semplicistico metodo getSequencedActivityIntent() che ho scritto, puoi aggiungere una logica più avanzata se necessario, magari usare una HashMap da associare ogni classe nella sequenza, con un valore di variabile arbitraria):?

public class MyActivity extends Activity { 

    public static class A extends MyActivity {} 
    public static class B extends MyActivity {} 
    public static class C extends MyActivity {} 
    public static class D extends MyActivity {} 
    public static class E extends MyActivity {} 
    public static class F extends MyActivity {} 
    public static class G extends MyActivity {} 
    public static class H extends MyActivity {} 
    public static class I extends MyActivity {} 
    public static class J extends MyActivity {} 

    private final static List<Class<?>> SEQUENCE = Arrays.asList(new Class<?>[] { 
      A.class, B.class, C.class, D.class, E.class, 
      F.class, G.class, H.class, I.class, J.class, 
    }); 

    private Intent getSequencedActivityIntent(int step) { 
     final int current = SEQUENCE.indexOf(this.getClass()); 
     if (current == -1) new Intent(this, SEQUENCE.get(0)); 

     final int target = current + step; 
     if (target < 0 || target > SEQUENCE.size() - 1) return null; 

     return new Intent(this, SEQUENCE.get(target)); 
    } 

    // the rest of your activity code 
} 

non dimenticare di aggiungere le loro voci al vostro AndroidManifest.file xml troppo (singleTop è facoltativo - impedirà l'istanza di attività nello stack da creare di nuovo quando riportato in primo piano):

<activity android:name=".MyActivity$A" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$B" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$C" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$D" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$E" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$F" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$G" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$H" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$I" android:launchMode="singleTop" /> 
    <activity android:name=".MyActivity$J" android:launchMode="singleTop" /> 

Ora, ogni volta che è necessario avviare una nuova istanza "top" della la vostra attività, è possibile fare qualcosa di simile:

final Intent intent = getSequencedActivityIntent(+1); 
    if (intent == null) return; 
    intent.putExtra("dataset", dataSet); 
    startActivity(intent); 

E quando si ha bisogno di tornare a uno dei esempio nel backstack si può fare:

final Intent intent = getSequencedActivityIntent(- stepBack); 
    if (intent == null) return; 
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    startActivity(intent); 
1

come ho underst e Android si rivolge solo alla classe di attività e non a una particolare istanza di attività. Quindi, penso che non sarai in grado di fare ciò che vuoi semplicemente aggiungendo alcune bandiere su Intent.

penso che l'approccio più semplice sarebbe quella di implementare sul proprio da qualcosa di simile

a) Creare alcune Singleton e hanno un elemento in essa che punta ad istanza di attività alla quale si desidera ritornare (come esempio di attività B). Probabilmente, dovrai archiviare tutte le attività in qualche elenco per essere in grado di ottenere l'istanza di un'attività precedentemente avviata.

b) Override onResume per tutte le attività e in essa fare seguente controllo:

if (SomeSingleton.getTargetActivity() != null && this != SomeSingleton.getTargetActivity()) 
    finish(); 
else 
    SomeSingleton.setTargetActivity(null); 

c) Non appena avete bisogno di tornare da E fai

SomeSingleton.setTargetActivity(B); 
finish(); 

questo modo si chiude l'attività superiore (che è E) e chiama su Riduci sull'attività D. Verificherà se è un bersaglio. Se non lo è, lo chiuderà e il sistema chiamerà su Riduci sull'attività C e così via.

2

È possibile indicizzare le vostre attività, senza doversi preoccupare di gestire tutta la catena di onActivityResult s utilizzando un super attività che si estendono in tutte le vostre attività

Ecco un'implementazione (non ho la prova), ma se si estendere questa Superattività in tutte le attività, è possibile chiamare fallBackToActivity(int) a qualsiasi attività utilizzando il proprio indice e ogni attività ha ora un getIndex(). Si può usare il fallback su un indice relativo come getIndex()-3

package sherif.android.stack.overflow; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 

public class SuperActivity extends Activity { 
    private static String EXTRA_INDEX = "SUPER_INDEX"; 
    private static int RESULT_FALLBACK = 0x123456; 
    private int index; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if(getIntent()!=null) { 
      index = getIntent().getIntExtra(EXTRA_INDEX, -1) + 1; 
     } 
    } 
    protected final int getIndex() { 
     return index; 
    } 
    protected final void fallBackToActivity(int index) { 
     Intent intent = new Intent(); 
     intent.putExtra(EXTRA_INDEX, index); 
     setResult(RESULT_FALLBACK, intent); 
     finish(); 
    } 
    @Override 
    public void startActivityForResult(Intent intent, int requestCode) { 
     intent.putExtra(EXTRA_INDEX, getIndex()); 
     super.startActivityForResult(intent, requestCode); 
    } 
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     if(resultCode == RESULT_FALLBACK) { 
      if(data.getIntExtra(EXTRA_INDEX, -1)!=getIndex()) { 
       setResult(RESULT_FALLBACK, data); 
       finish(); 
      } 
     } 
    } 
} 
1

Se si desidera utilizzare un approccio anomalo, o qualche volta difficile, si avrà più problemi in seguito. Penso che sia possibile

Definire una sottoclasse di attività astratta/non astratta e definire tutto ciò che si desidera. Se altre classi sono esattamente uguali a quelle della classe precedente, quindi basta sottoclasse da essa e non fare nient'altro. Ma se le classi (Attività) possono essere diverse l'una dall'altra, puoi fornire metodi astratti/non astratti per definire abilità aggiuntive.

Così

  • si scrive un codice riutilizzabile per tutte le attività,
  • di agire normale in modo da ottenere un buon risultato
  • È possibile controllare tutto, specializzata nelle attività
  • È possibile controllare pila utilizzando file manifest
  • e altro

per informazioni dettagliate vedere di seguito i codici:

Parent attività:

public abstract class AbstractActivity extends Activity { 

    AbstractActivity currentActivity; 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     currentActivity = this; 
     someProtectedMethod(); 
     commonMethod(); 
     // etc... 

     /* event handling */ 
     Button btn_first = (Button) findViewById(R.id.btn_first); 
     Button btn_second = (Button) findViewById(R.id.btn_second); 

     btn_first.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(currentActivity, FirstActivity.class); 
       currentActivity.startActivity(intent); 
      } 
     }); 

     btn_second.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(currentActivity, SecondActivity.class); 
       currentActivity.startActivity(intent); 
      } 
     }); 

    } 


    /** you must override it, so you can control specified things safe */ 
    protected abstract void someProtectedMethod(); 


    protected void commonMethod() { 
     Log.i("LOG", "Hello From " + getClass().getName()); 
    } 


    @Override 
    protected void onResume() { 
     super.onResume(); 
     //some statement that work in all activities to 
     Log.i("LOG", "On Resume: " + getClass().getName()); 
    } 
} 

prima azione:

public class FirstActivity extends AbstractActivity { 

    @Override 
    protected void someProtectedMethod() { 
     Log.i("LOG", "Special Action From First Activity"); 
    } 
} 

Seconda azione:

public class SecondActivity extends AbstractActivity { 

    @Override 
    protected void someProtectedMethod() { 
     Log.i("LOG", "Special Action From Second Activity"); 
    } 
} 

main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="horizontal" > 


    <Button 
     android:id="@+id/btn_first" 
     android:layout_width="0dip" 
     android:layout_height="wrap_content" 
     android:layout_weight="0.5" 
     android:text="Open First Activity" /> 

    <Button 
     android:id="@+id/btn_second" 
     android:layout_width="0dip" 
     android:layout_height="wrap_content" 
     android:layout_weight="0.5" 
     android:text="Open Second Activity" /> 

</LinearLayout> 

manifesto:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.activity_control" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="7" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".FirstActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <activity 
      android:name=".SecondActivity" 
      android:label="@string/app_name" > 
     </activity> 

    </application> 

</manifest> 
Problemi correlati