9

このコードを使用してアクティビティ スタックに戻ります (主にホーム アクティビティに移動するため)。

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


したがって、新しいインテントを作成し、「ターゲット」をアクティビティスタックにある HomeActivity に設定して、スタック全体がこの HomeActivity まで上からクリアされるようにします。
ここで、少し異なるユースケースが必要です。たとえば、スタックに 5 つのアクティビティ ABCDE (A が B などを開始) があります。ここで、ユーザーの選択に応じて、E から C または B にジャンプする必要があります。問題は、アクティビティ A、B、C、D、E のクラスが同じであることです。そのため、そのアクティビティをターゲットにする方法がわからないため、上記の例を使用できません。
したがって、問題は、「アクティビティにタグを付ける」方法やスタックを操作する方法があるかどうかです。
ありがとう!

4

7 に答える 7

3

onActivityResultすべてのアクティビティで拡張するスーパー アクティビティを使用して、 のすべてのチェーンを処理することを心配することなく、アクティビティにインデックスを付けることができます

これが実装です (私はテストしませんでした) が、この SuperActivity をすべてのアクティビティで拡張すると、fallBackToActivity( int )そのインデックスを使用して任意のアクティビティを呼び出すことができ、各アクティビティには getIndex() が追加されます。次のような相対インデックスにフォールバックするために使用できます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();
            }
        }
    }
}
于 2012-08-31T12:39:10.683 に答える
3

私はそれを自分で試したことはありませんが、アプリをリファクタリングしFragmentて単一の s のスタックを使用するのが最善の方法だと思います (提供されたandメソッドActivityを使用してバックスタックをより簡単に管理できるため)。基本的にこれには、アクティビティ内のほとんどのコードをフラグメントに移動してから、バックスタック操作コードをアクティビティに追加する必要があります)。(API 11+ を使用する) のコードまたは(互換性ライブラリで使用する) HanselAndGretelのコードを見て、これを実装する方法を確認できます。addToBackStack()popBackStack()FragmentBreadCrumbs

ただし、現在のマルチ アクティビティ アプローチを引き続き使用したい場合は、これを行う方法を説明するために私が思いついたコードを次に示します。

まず、いくつかの内部クラスを追加して現在のアクティビティのエイリアスを作成し、これらのクラスをシーケンス リストに配置します (getSequencedActivityIntent()私が書いた単純な方法にも注意してください。必要に応じて、より高度なロジックを追加できます。おそらく HashMap を使用して、シーケンス内の各クラスを関連付けます)。任意のタグ値で?):

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
}

それらのエントリを AndroidManifest.xml ファイルにも追加することを忘れないでください (singleTopオプションです。最前面に戻されたときに、スタック内の Activity インスタンスが再度作成されるのを防ぎます)。

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

これで、アクティビティの新しい「トップ」インスタンスを開始する必要があるときはいつでも、次のようなことができます:

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

バックスタック内のインスタンスの 1 つに戻る必要がある場合は、次のようにします。

    final Intent intent = getSequencedActivityIntent(- stepBack);
    if (intent == null) return;
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
于 2012-08-28T17:26:13.023 に答える
2

私が理解しているように、Android はアクティビティの特定のインスタンスではなく、アクティビティのクラスのみを対象としています。したがって、Intent にフラグを追加するだけでは、やりたいことはできないと思います。

このような方法で自分で実装するのが最も簡単な方法だと思います

a)いくつかのシングルトンを作成し、その中に戻りたいアクティビティのインスタンスを指すメンバーを含めます(アクティビティBの例として)。おそらく、以前に起動されたアクティビティのインスタンスを取得できるようにするには、すべてのアクティビティを何らかのリストに保存する必要があります。

b) すべてのアクティビティの onResume をオーバーライドし、次のチェックを行います。

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

c) E から戻る必要がある場合はすぐに行う

SomeSingleton.setTargetActivity(B);
finish();

これにより、トップ アクティビティ (E) が閉じられ、アクティビティ D で onResume が呼び出されます。それがターゲットかどうかがチェックされます。そうでない場合は閉じ、システムはアクティビティ C で onResume を呼び出します。

于 2012-08-29T21:06:52.760 に答える
2

アクティビティに何をするかを指示するインテントに追加します。例えば

    intent.putExtra("STATE", 1);

アクティビティの onCreate でこの値を取得します。

  getIntent().getExtras()
于 2012-08-23T11:20:29.297 に答える
2

(これまでのところ) 最善かつ最も簡単な解決策は、Fragments と FragmentManager を使用することです。次に、各 Fragment にタグを付けて FragmentManager を使用します。アクティビティのみを使用すると、ほぼ同じ結果を得ることが非常に困難になる可能性があります。

于 2012-09-03T13:05:56.010 に答える
2

異常なアプローチを使用したり、一度トリッキーなアプローチを使用したりすると、後でさらに問題が発生します。できると思います

Activity の抽象/非抽象サブクラスを定義し、必要なものをすべて定義します。他のクラスが上記のクラスとまったく同じである場合は、それをサブクラス化して、それ以上何もしません。ただし、クラス (アクティビティ) が互いに異なる可能性がある場合は、抽象/非抽象メソッドを提供して追加の機能を定義できます。

そう

  • すべてのアクティビティに対して再利用可能なコードを作成し、
  • 普通に振る舞うから良い結果が得られる
  • アクティビティに特化したすべてをコントロールできます
  • マニフェストファイルを使用してスタックを制御できます
  • もっと

詳細については、以下のコードを参照してください。

親のアクティビティ:

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

最初のアクティビティ:

public class FirstActivity extends AbstractActivity {

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

2 番目のアクティビティ:

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>

マニフェスト:

<?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>
于 2012-09-01T04:17:50.283 に答える
2

ユーザーがこのアイテムを選択してBクラスにインテントを渡し、ユーザーがそのアイテムをCクラスに渡すインテントを選択した場合、ステートメントに条件を保持することができます

于 2012-08-23T11:18:17.213 に答える