Android 组织碎片活动导航堆栈
应用程序(目标API级别必须为7)具有Android 组织碎片活动导航堆栈,android,android-intent,android-activity,Android,Android Intent,Android Activity,应用程序(目标API级别必须为7)具有FragmentActivity,它在onCreate分析作为额外密钥传递的片段密钥 现在需要的是重新排序到前面已经用给定的片段键创建的活动 假设具有不同片段键的FragmentActivity是FA1、FA2和FA3——每个都是具有不同片段的相同活动类实例 现在,在堆栈FA1FA2FA3中,我想使用intent而不是back按钮进入FA2,默认情况下,这会给出: FA1FA2FA3>新增FA2 我想得到FA1FA3FA2,因为FA3可能有一些挂起的操作,F
FragmentActivity
,它在onCreate
分析作为额外密钥传递的片段密钥
现在需要的是重新排序到前面已经用给定的片段键创建的活动
假设具有不同片段键的FragmentActivity
是FA1
、FA2
和FA3
——每个都是具有不同片段的相同活动类实例
现在,在堆栈FA1
FA2
FA3
中,我想使用intent而不是back按钮进入FA2
,默认情况下,这会给出:
FA1
FA2
FA3
>新增FA2
我想得到FA1
FA3
FA2
,因为FA3
可能有一些挂起的操作,FA1
FA2
没有默认值好,但肯定比默认值好
如果有多个活动,我会使用标志\u ACTIVITY\u REORDER\u TO\u FRONT
标志来表示意图,但在这种情况下不起作用
FA1、FA2、FA3等。
都是同一类的实例MyFA
,这就是为什么我不能使用intent标志,而FragmentManager似乎在出现标准的全局碎片缓存之前帮不上忙
里程碑(目前正在工作,有待改进)解决方案我今天学到的一件事是,允许为同一活动制作多个别名,并将不同的意图附加项用作id。现在有了REORDER_TO_FRONT标志,它可以按照我的要求工作 解决方案反馈解决方案没有低级操作,我更喜欢在任务或后台挖掘。现在的缺点是,每个这样的活动都需要一个带有硬编码路径的单独别名,我不太喜欢它 需求(赏金在这里)任何一个拥有合理优化的人都会得到150300块饼干。不错吧?任何其他固溶体也受到高度赞赏 目前我在应用程序清单上有10个别名,例如
<activity
android:name=".activity.FragmentActivity"
android:configChanges="orientation"
android:screenOrientation="portrait" >
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="com.company.name.intent.FragmentActivity" />
</intent-filter>
</activity>
<activity-alias
android:name="com.company.name.intent.FragmentActivity.FragmentedOne"
android:targetActivity=".activity.FragmentActivity" >
<intent-filter>
<action android:name="com.company.name.intent.FragmentActivity.FragmentedOne" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="fragment_key_extra"
android:value="FragmentOne" />
</activity-alias>
<activity-alias
android:name="com.company.name.intent.FragmentActivity.FragmentedTwo"
android:targetActivity=".activity.FragmentActivity" >
<intent-filter>
<action android:name="com.company.name.intent.FragmentActivity.FragmentedTwo" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="fragment_key_extra"
android:value="FragmentTwo" />
</activity-alias>
您可以研究如何使用提供的功能。它具有
popbackbackstack
等功能
您还可以使用将片段添加到Backback。您可以使用addToBackStack
来完成此操作
因此,有了这两个类,您应该能够根据需要在backbackback中重新排序您的片段。这个答案相当于300个cookies:-D mmmm
//This is our very own back stack.
private ArrayList<Intent> backStack = new ArrayList<Intent>();
public void reorderBackStack(){
//Do what you want to the order of your backstack
//You can read the value of your intent extras from here.
}
public void addIntent(Intent i){ // this gets called from our activities onCreate
backStack.add(i);
}
public void goBack(){
if(backStack.size() >= 2){ // can go back
backStack.remove(backStack.size() - 1); // drop the last item in stack if you want. This is how Android does it. (no forward capability)
this.startActivity(backStack.get(backStack.size() - 1));
}
}
}- 专业人士
- 没有别名
- 完全动态且可重用
- 低电平控制
- 易于使用(扩展CustomBackbackActivity而不是FragmentActivity或Activity)
- 缺点
- 不是现成的解决方案。将需要调整和调试
FragmentActivity
中,为从片段到活动的回调实现一个接口
2.当您启动任何片段时,请将其与参数或标记一起放入后堆栈中(addToBackStack(String arg0))
,在该参数的帮助下,您可以弹出该标记
3.当需要对片段进行重新排序时,请调用接口的方法,该方法根据需要使用适当的参数实现,然后使用popBackStack(字符串arg1,字符串arg2)
获取带有标记的片段,标记放在backstack中。我已经回答了类似的问题,但解决方案不是最好的,因为FA1>FA2>FA3会将您带到FA1>FA2,而不是FA1>FA3>FA2
无论如何,我对代码进行了一些编辑,以使用一个“标记”,它将是一个字符串,但我认为您可以使用使用整数索引的主要解决方案。总之,这应该允许您使用某个标记返回活动。我不确定每个活动如何决定它的标签,但在我之前的回答中,这是一个简单的递增整数问题
package sherif.android.stack.overflow;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class SuperActivity extends FragmentActivity {
private static String EXTRA_INDEX = "SUPER_INDEX";
private static int RESULT_FALLBACK = 0x123456;
private String tag; //this is your tag
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(getIntent()!=null) {
tag = getIntent().getStringExtra(EXTRA_INDEX, "default_tag");
}
}
protected final String getIndex() {
return tag;
}
protected final void fallBackToActivity(String tag) {
Intent intent = new Intent();
intent.putExtra(EXTRA_INDEX, tag);
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.getStringExtra(EXTRA_INDEX, "default_tag").equals(getIndex())) {
setResult(RESULT_FALLBACK, data);
finish();
}
}
}
}
基于您使用activity alias
解决此问题的想法,我编写了一个解决方案,将执行以下操作:
- 扫描程序包中的活动列表以查找特定活动的别名
- 设置将每个别名映射到目标的查找表
- 提供一个
startActivity()
和activitydestromed()
方法,这些方法将进行一些簿记,以便可以使用查找表根据意图动态地为正在运行的活动分配别名
下面是一个关于如何使用它的示例:
- 在AndroidManifest.xml中
<activity android:name=".MyFragmentActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity-alias android:name=".Alias0" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias1" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias2" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias3" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias4" android:targetActivity=".MyFragmentActivity" />
您可以这样做:
Intent intent = new Intent(this, MyFragmentActivity.class);
intent.putExtra("title", newActivityTitle);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
mHistorian.startActivity(this, intent);
因此,您仍然需要将一些活动别名
手动添加到清单中(用作池),并在活动中实现matchIntent()
方法(以帮助检测两个意图是否等于您),但其余的由Historian类动态处理
我还没有对代码进行详尽的测试,但在某些sim卡上似乎工作得很好
<activity android:name=".MyFragmentActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity-alias android:name=".Alias0" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias1" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias2" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias3" android:targetActivity=".MyFragmentActivity" />
<activity-alias android:name=".Alias4" android:targetActivity=".MyFragmentActivity" />
public class MyFragmentActivity extends FragmentActivity
implements Historian.Host {
private Historian<MyFragmentActivity> mHistorian;
// ...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mHistorian = new Historian<MyFragmentActivity>(this);
// ...
}
@Override
protected void onDestroy() {
super.onDestroy();
mHistorian.activityDestroyed(this);
}
@Override
public boolean matchIntent(Intent intent0, Intent intent1) {
if (intent0 == null || intent1 == null) return false;
final String title0 = intent0.getStringExtra("title");
final String title1 = intent1.getStringExtra("title");
return title0.equals(title1);
}
// ...
}
Intent intent = new Intent(this, MyFragmentActivity.class);
intent.putExtra("title", newActivityTitle);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
Intent intent = new Intent(this, MyFragmentActivity.class);
intent.putExtra("title", newActivityTitle);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
mHistorian.startActivity(this, intent);