从另一个 Activity 返回后返回 MainActivity 的片段?
Posted
技术标签:
【中文标题】从另一个 Activity 返回后返回 MainActivity 的片段?【英文标题】:Returning to MainActivity's fragment after return back from another Activity? 【发布时间】:2017-12-22 19:51:03 【问题描述】:我有两个活动:MainActivity 和 OtherActivity。 MainActivity 中的片段会启动 OtherActivity,但是当我按下顶部的后退按钮时,它会将我返回到 MainActivity 而不是片段启动OtherActivity。
最终结果是最终用户被送回主屏幕,而不是他们正在使用的片段。
这是我的清单。我已将 MainActivity 设置为 OtherActivity 的父级:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".OtherActivity"
android:parentActivityName="com.example.test.MainActivity" >
</activity>
在MainActivity中,当用户点击一个按钮时,它会加载一个List片段:
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
button.findViewById(R.id.events).setOnClickListener(new View.OnClickListener()
Fragment ef = new MyItemsFragment();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.content, ef, "my_fragment");
fragmentTransaction.commit();
);
public void callOtherActivity()
Intent i = new Intent(this, OtherActivity.class);
this.startActivity(i);
当在 List Fragment 中单击一个项目时,它会启动 OtherActivity。很多代码都是由 android studio 自动生成的。我已经改变了一些。在 MyItemsRecyclerViewAdapter 中:
@Override
public void onBindViewHolder(final ViewHolder holder, int position)
holder.mItem = mValues.get(position);
holder.mView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (null != mListener)
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mListener.onEventFragmentInteraction(holder.mItem);
MainActivity ma = (MainActivity) holder.mView.getContext();
ma.callOtherActivity();
);
注意它调用ma.callOtherActivity()
,它是在MainActivity中定义的,当在列表片段中点击一个项目时会启动OtherActivity。
这是OtherActivity:
public class OtherActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
现在,当我单击 OtherActivity 中的后退箭头按钮时,应用程序将只显示 MainActivity,而不是用户上次看到的 List 片段。
如何确保从 OtherActivity 返回时,用户将再次看到列表片段以获得更好的用户体验?
编辑:“后退”按钮似乎有些混乱。也许它们是相同的,但我说的是切换活动时的那个。它不是用于退出应用程序的后退按钮。 See image
【问题讨论】:
在调用fragment时尝试删除addToBackStack(null)看看 从清单文件中删除 android:parentActivityName="com.example.test.MainActivity" 并尝试。当您单击后退按钮时,它基本上会将 MainActivity 作为新活动启动。请让我知道是否我错了。 只有一个“返回”按钮,通常用于导航返回堆栈。我认为您的更新是说您指的是“向上”按钮。 developer.android.com/training/appbar/up-action.html 【参考方案1】:当您开始一项新 Activity 时,现有的 Activity 会被堆叠起来,以便您稍后可以检索它,例如按下 Back 键时。
按下返回键后,Activity 会重新启动。这是重要的部分。它不仅恢复到上次使用时的状态。这意味着您作为开发人员必须注意将 Activity 恢复到您希望它处于的状态。任何片段都将处于正确的状态,但您必须注意不要在 Activity 重新启动时覆盖该状态。
在您的情况下,我怀疑您的 MainActivity 代码不加选择地重新初始化您的片段,而不是检查该特定活动的片段是否已经存在,然后才有条件地初始化它们,除非它们不存在。
很难确定,因为您的问题中没有包含任何代码。检查在 MainActivity 中显示片段的代码。在显示它们之前,您是否检查是否已经有可见的片段?如果没有,你应该是。
例如,下面的代码在一个 Activity 中,首先检查一个片段是否已经显示,然后再添加一个新片段。本质上,第一次运行时,将没有 Fragment,因此 existing
将为空,并且将创建并显示一个新的 Fragment。
在您开始一个新的OtherActivity
等然后使用返回键返回此活动后,existing
将不再为空,因为 Fragment 系统会将所有现有的 Fragment 恢复到您的容器中。因此我们实际上什么都不做。
@Override
protected void onCreate(Bundle b)
super.onCreate(b);
Fragment existing = getSupportFragmentManager().findFragmentById(R.id.content);
if (existing == null)
Fragment newFragment = new MyFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.content, newFragment)
.commit();
希望这很清楚。
【讨论】:
那个片段已经加载了数据,所以我有fragmentTransaction.addToBackStack(null);
。当主要活动从其他活动返回后重新启动时,我不能从后台恢复这个吗?
R.id.content
实际上是主要活动的内容。那应该是片段,所以.findFragmentByTag("my_fragment")
,因为我在单击按钮后在事务中为它创建了一个标签?但如果它存在,我如何用它的现有数据加载它?如果不存在任何内容,您的示例会从头开始重新创建片段。
我的建议(和代码示例)相当笼统,因为您没有包含任何片段创建代码。它可能相关,也可能不相关,但这是我看到人们犯的一个常见错误,您对问题的描述听起来像是一个可能的原因。【参考方案2】:
删除这行fragmentTransaction.addToBackStack(null);
【讨论】:
【参考方案3】:您可以使用 getSupportFragmentManager().getBackStackEntryCount(); MainActivity 的 onBackPressed 方法中的方法。 OnClick 底部系统后退按钮。 按照下面的方法。
@Override
public void onBackPressed()
int backstack = getSupportFragmentManager().getBackStackEntryCount();
if (backstack > 0)
getSupportFragmentManager().popBackStack();
else
super.onBackPressed();
System.exit(0);
在片段中,按顶部的后退按钮。 尝试这个, 在Fragment的onCreate方法或者onCreateView方法中调用这个默认方法
setHasOptionsMenu(true);
然后覆盖下面的方法:
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case android.R.id.home:
getFragmentManager().popBackStack();
break;
return super.onOptionsItemSelected(item);
【讨论】:
【参考方案4】:您可以使用 Activity 作为此启动 Other Activity 的结果,一旦您想完成 OtherActivity 只需执行 setResult,MainActivity 将收到此结果并执行以下操作
if (getSupportFragmentManager().getBackStackEntryCount() > 0)
getSupportFragmentManager().popBackStack();
MainActivity 中的代码如下所示
public void callOtherActivity()
Intent i = new Intent(this, OtherActivity.class);
startActivityForResult(i, 1);
并在OtherActivity的onBackPress调用下面的方法。
Intent returnIntent = new Intent();
returnIntent.putExtra("result",result);
setResult(Activity.RESULT_OK,returnIntent);
finish();
现在在 MainActivity onActivityresult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
if (requestCode == 1)
if (getSupportFragmentManager().getBackStackEntryCount() > 0)
getSupportFragmentManager().popBackStack();
【讨论】:
【参考方案5】:我可能会迟到,但在我的情况下,由于 MainActivity 的 OnStart 方法中的 LoadFragment 方法出现错误
【讨论】:
以上是关于从另一个 Activity 返回后返回 MainActivity 的片段?的主要内容,如果未能解决你的问题,请参考以下文章
从另一个 Activity 返回的错误 requestCode onActivityResult