2012-08-23 15 views
7

używam tego kodu, aby przejść z powrotem w stos działalności (głównie, aby przejść do działalności gospodarczej):Jak oznaczyć aktywność

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


Więc tworzę nową Intent i ustaw „target”, który jest do HomeActivity w stosie aktywności, więc cały stos zostanie usunięty z góry do tego HomeActivity.
Teraz potrzebuję trochę innego zastosowania. Mam na przykład pięć działań A-B-C-D-E (A rozpoczął B itd.) Na stosie. Teraz muszę przeskoczyć z E na C lub B w zależności od tego, co wybierze użytkownik. Problem polega na tym, że działania A, B, C, D, E mają tę samą klasę. Tak więc nie mogę użyć powyższego przykładu, ponieważ nie wiem, jak kierować tę aktywność.
Pytanie brzmi, czy istnieje sposób "tagowania aktywności" lub manipulowania stosem.
Dzięki!

+0

jeśli A i E są takie same, zamiast wywoływania E dlaczego nie wywołujesz aktywności A z historii? – Ishtiaq

+0

Poprawiłem moje pytanie, aby było jaśniejsze. Wszystkie zajęcia mają tę samą klasę. – Warlock

+0

Nie mogę zrozumieć twojego problemu. Proszę powiedz mi, co jest złe? –

Odpowiedz

0

Najlepszym i najprostszym rozwiązaniem (do tej pory) będzie wykorzystanie Fragmenty i FragmentManager. Następnie oznacz każdy Fragment i użyj FragmentManager. Używanie tylko Aktywności może być bardzo trudne mieć prawie taki sam wynik.

+0

Wspomniałem o tym w mojej odpowiedzi! :) – Joe

+0

Twoje podejście jest zupełnie inne. Ale dzięki za ten pomysł! ;-) – Warlock

1

można po prostu zachować stan, w wyciągu jeśli użytkownik wybierze ten element przechodzić zamiar klasy B i jeśli użytkownik wybierze tę pozycję przekazać intencję do C klasy

+0

Problem polega na tym, że wszystkie zajęcia mają tę samą klasę. – Warlock

1

Dodaj extra do swojej intencji, które będą wskazywać na aktywność co robić. Na przykład

intent.putExtra("STATE", 1); 

i uzyskać tę wartość w onCreate swojej działalności.

getIntent().getExtras() 
+0

Imho jedynym sposobem użycia tego podejścia jest połączenie go z funkcjami startActivityForResult/onActivityResult itp., Ale miałem nadzieję, że jest to możliwe w prostszy sposób. Mogę mieć dziesięć działań wymienionych powyżej, więc onActivityResult będzie wywoływany wiele razy ... – Warlock

+0

Jeśli głównym problemem jest ta sama klasa dla wszystkich działań, rozwiązanie może być proste. Utwórz klasę podstawową, a następnie rozszerz ją tyle razy, ile potrzebujesz, i stwórz różne klasy. Ale myślę, że to dziwne podejście. Lepiej stwórz prostą maszynę państwową i nie uruchamiaj ponownie tej samej czynności 100 razy ... – Dimanoid

2

nie próbowałem go samodzielnie, ale myślę, że najlepszym rozwiązaniem byłoby byłaby swoją aplikację do korzystania stos Fragment s ramach jednej Activity (ponieważ można wtedy łatwiej zarządzać backstack pomocą dostarczone metody addToBackStack() i popBackStack()). Zasadniczo polega to na przeniesieniu większości kodu w Aktywności do Fragmentu, a następnie dodaniu kodu manipulacyjnego Backstack w Aktywności). Możesz spojrzeć na kod FragmentBreadCrumbs (z API 11+) lub kod dla HanselAndGretel (do użytku z biblioteką kompatybilności), aby zobaczyć, jak można to zaimplementować.

Jeśli jednak chcesz nadal korzystać z aktualnego podejścia dla wielu działań, poniżej przedstawiono kod, który wymyśliłem, aby zilustrować, w jaki sposób możesz to zrobić.

Najpierw dodaj kilka klas wewnętrznych do aliasu bieżącej aktywności i umieść te klasy w liście sekwencji (zauważ także uproszczoną metodę, którą napisałem, możesz dodać bardziej zaawansowaną logikę, jeśli potrzebujesz - może użyć HashMap do kojarzenia każda klasa w sekwencji o dowolnej wartości znacznika):

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 
} 

nie zapomnij dodać swoje wpisy do AndroidManifest.plik xml zbyt (singleTop jest opcjonalna - będzie to uniemożliwić wystąpienie aktywny w stosie być ponownie utworzone podczas sprowadzony do przodu):

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

Teraz, kiedy trzeba rozpocząć nowy „top” instancję Twój aktywny, można zrobić coś takiego:

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

a kiedy trzeba wrócić do jednej instancji w backstack można zrobić:

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

Jak underst Android kieruje się wyłącznie na klasę aktywności, a nie na konkretną instancję działania. Myślę więc, że nie będziesz w stanie zrobić tego, czego chcesz, po prostu dodając flagi w intencji.

Myślę, że najprostszym rozwiązaniem byłoby wdrożyć go na własną rękę przez coś takiego

a) utworzyć kilka singleton i posiada element w nim co wskazuje na przykład aktywności, do której chcesz wrócić (jak przykładowa aktywność B). Prawdopodobnie będziesz musiał przechowywać wszystkie działania na niektórych listach, aby móc pobrać wystąpienie wcześniej uruchomionej aktywności.

b) Przestawianie onResume dla wszystkich rodzajów działalności, aw nim zrobić następujące sprawdzenia:

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

c) Jak najszybciej trzeba powrócić z E zrobić

SomeSingleton.setTargetActivity(B); 
finish(); 

Spowoduje to zamknięcie najwyższej aktywności (który jest E) i wywołać onResume na aktywności D. Sprawdza, czy jest to cel. Jeśli nie, to zostanie zamknięte, a system wywoła onResume w działaniu C i tak dalej.

2

Można Indeks swoje działania bez konieczności martwienia się o obsługę cały łańcuch onActivityResult s przy użyciu super aktywny które rozciągają się we wszystkich swoich działaniach

Oto implementacja (nie przetestować go), ale jeśli przedłużyć tę SuperActivity we wszystkich swoich działaniach, możesz zadzwonić pod numer fallBackToActivity(int) do dowolnej aktywności za pomocą jej indeksu, a każde działanie ma teraz getIndex(). Można go używać do awaryjny do indeksu względnej jak 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

Jeśli chcesz użyć nienormalne podejście lub niektóre trudne raz, będziesz miał więcej problemów później. Myślę, że możesz zdefiniować abstrakcyjną/nie abstrakcyjną podklasę działania i zdefiniować wszystko, co chcesz, podając

. Jeśli inne klasy są dokładnie takie same, jak powyższa klasa, więc po prostu je podklasuj i nic więcej nie rób. Ale jeśli klasy (zajęcia) mogą się różnić od siebie, możesz podać abstrakcyjne/nie abstrakcyjne metody definiowania dodatkowych umiejętności.

Więc

  • Piszesz wielokrotnego użytku kody dla wszystkich rodzajów działalności,
  • Zachowujesz normalne, więc dostaniesz dobry wynik
  • Można kontrolować wszystko specjalizującą się w swoim aktywnosci
  • Można kontrolować stos przy użyciu pliku manifestu
  • i więcej

celu uzyskania szczegółowych informacji patrz niżej kody:

Parent Aktywny:

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

pierwszą aktywność:

public class FirstActivity extends AbstractActivity { 

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

Second Aktywny:

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> 

Oczywisty:

<?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> 
Powiązane problemy