dynamic设置父级活动

所以目前我有一个可以从两个不同的活动中获得的活动,问题是我只能将一个活动设置为清单XML文件中的父活动。 显然,这是糟糕的用户体验/用户界面devise,因为活动可能会将用户返回到以前的错误活动,所以我试图dynamic设置哪个活动是父活动。

麻烦的是我不太清楚如何去做这个,无论是在代码或XML,所以任何指针赞赏。 🙂

这里有两个概念“上”和“后”。 “回”是显而易见的:把我带到我刚到这里之前的地方。 通常你不需要关心“返回”,因为系统可以处理它。 “向上”并不是那么明显 – 这就像缩小 – 从元素到集合,从细节到更广阔的画面。

这些适合你的用例?


按照下面的注释:向上button从android清单中拉取目的地,但是可以通过程序自定义 。

对于将来的读者来说,这里是一个如何根据开发人员指南实际执行正式/合适解决scheme的例子(滚动到以“当父代活动可能不同时这是适当的”为开头的段落)。

请注意,此解决scheme假定您正在使用支持库来实现您的ActionBar ,并且您至less可以在您的清单XML文件中设置“默认”父活动,以便在您退出的活动位于“任务”这不属于你的应用程序(阅读链接的文档澄清)。

 // Override BOTH getSupportParentActivityIntent() AND getParentActivityIntent() because // if your device is running on API 11+ it will call the native // getParentActivityIntent() method instead of the support version. // The docs do **NOT** make this part clear and it is important! @Override public Intent getSupportParentActivityIntent() { return getParentActivityIntentImpl(); } @Override public Intent getParentActivityIntent() { return getParentActivityIntentImpl(); } private Intent getParentActivityIntentImpl() { Intent i = null; // Here you need to do some logic to determine from which Activity you came. // example: you could pass a variable through your Intent extras and check that. if (parentIsActivityA) { i = new Intent(this, ActivityA.class); // set any flags or extras that you need. // If you are reusing the previous Activity (ie bringing it to the top // without re-creating a new instance) set these flags: i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); // if you are re-using the parent Activity you may not need to set any extras i.putExtra("someExtra", "whateverYouNeed"); } else { i = new Intent(this, ActivityB.class); // same comments as above i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); i.putExtra("someExtra", "whateverYouNeed"); } return i; } 

注意:如果您没有在清单XML文件中设置默认的父Activity,那么您还需要实现onCreateSupportNavigateUpTaskStack(),因为系统不知道如何为您的任务生成一个backstack。 我没有提供任何这个部分的例子。

我对finish()types的解决scheme的想法

在我寻找这个问题的解决scheme时,我遇到了一些提倡覆盖onOptionsItemSelected()和拦截android.R.id.homebutton的方法,这样他们可以简单地finish()当前的Activity返回到前一个屏幕。

在许多情况下,这将达到预期的行为,但我只想指出,这绝对不是一个正确的UP导航相同。 如果您是通过其中一项父活动导航到子活动,则finish()将返回到正确的上一个屏幕,但是如果通过通知input子活动,该怎么办? 在这种情况下,通过点击UPbutton来finish()回放)会使您直接回到主屏幕或您在查看通知之前查看的任何应用程序,而应该已经将您发送到您的应用程序中的适当的父Activity。

像这样,您可以dynamic导航到您的父级活动:

 getActionBar().setDisplayHomeAsUpEnabled(true); @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); } 

注意:它会将您redirect到您来自的活动或片段,而不pipe它是否是家长。 点击操作栏的上/主button将会完成当前的活动。

要了解如何正确使用Up Navigation,请参阅此Android开发者指南。

请注意,在上面的Android开发指南中有一个很大的缺陷,因为NavUtils函数对于ICS(和更低版本)和JellyBean(和更高版本)的工作方式不同。 NavUtils中的这个缺陷在这里被很好地解释。

重写的方法是getParentActivityIntent。

这是我的代码,完美的工作。

 @Override public Intent getParentActivityIntent() { Intent parentIntent= getIntent(); String className = parentIntent.getStringExtra("ParentClassSource"); Intent newIntent=null; try { //you need to define the class with package name newIntent = new Intent(OnMap.this, Class.forName(className)); } catch (ClassNotFoundException e) { e.printStackTrace(); } return newIntent; } 

从父母的活动;

 Intent i = new Intent(DataDetailsItem.this, OnMap.class); i.putExtra("ParentClassSource", "com.package.example.YourParentActivity"); startActivity(i); 

一般来说,一个“细节”types的活动必须提供“向上”的导航,如果它有嵌套/相关的内容。 “后退”导航由系统处理,因此您不必担心。

现在为了支持“向上的”导航,额外的努力有以下几种方式:

  1. 具有在AndroidManifest中定义的父活动的活动。

     Your Android Manifest --------------------- <activity android:name="com.example.app.DetailActivity" android:parentActivityName="com.example.app.MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.app.MainActivity" /> </activity> Your Detail Activity -------------------- @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); } 

    如果只有一个父活动,这就意味着(DetailActivity)总是从(MainActivity)启动。 否则,如果(DetailActivity)从不同的地方启动,则此解决scheme将不起作用。 更多在这里: http : //developer.android.com/training/implementing-navigation/ancestral.html

  2. (更容易和推荐)活动与片段和片段后备堆栈:

     Your Detail Activity -------------------- protected void replaceFragment(Bundle fragmentArguments, boolean addToBackStack) { DetailFragment fragment = new DetailFragment(); fragment.setArguments(fragmentArguments); // get your fragment manager, native/support FragmentTransaction tr = fragmentManager.beginTransaction(); tr.replace(containerResId, fragment); if (addToBackStack) { tr.addToBackStack(null); } tr.commit(); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; } return super.onOptionsItemSelected(item); } 

    在这种解决scheme中,如果用户按下“后退”,片段将从片段后台堆栈中popup,并且用户被恢复到前一片段,同时仍保持在相同的活动中。 如果用户按下“向上”,则活动解散并且用户被引导回到先前的活动(作为父活动)。 这里的关键是使用片段作为您的用户界面和作为片段主机的活动。

希望这可以帮助。

你将需要跟踪父母的活动。 一种方法是将其作为额外的存储来创build,以启动子活动)。 例如,如果活动A启动活动B,则将A的意图存储在为B创build的意图中。然后在B的onOptionsItemSelected中处理向上导航的位置,检索A的意图并使用所需的意图标志启动它。

下面的文章有一个更复杂的用例与一连串的儿童活动。 它解释了如何导航到父级的相同或新的实例,并在完成中间活动时完成。

Android向上导航多个父母的活动