从另一个 Activity 返回后返回 MainActivity 的片段?

Posted

技术标签:

【中文标题】从另一个 Activity 返回后返回 MainActivity 的片段?【英文标题】:Returning to MainActivity's fragment after return back from another Activity? 【发布时间】:2017-12-22 19:51:03 【问题描述】:

我有两个活动:MainActivityOtherActivityMainActivity 中的片段会启动 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

从另一个活动返回后防止recyclerview重新加载

从另一个活动返回后如何恢复活动中最后打开的片段

如果 setIconifiedByDefault 为 false,则从另一个意图返回时键盘弹出

从另一个 Activity 刷新 Recyclerview

当我们从另一个活动返回时如何刷新活动的数据?