【问题标题】:Activity restart on rotation Android旋转Android上的活动重启
【发布时间】:2010-10-02 03:44:44
【问题描述】:

在我的 Android 应用程序中,当我旋转设备(滑出键盘)时,我的 Activity 会重新启动(onCreate 会被调用)。现在,这可能是它应该的样子,但我在 onCreate 方法中做了很多初始设置,所以我需要:

  1. 将所有初始设置放在另一个函数中,这样它就不会在设备旋转时全部丢失或
  2. onCreate 不再被调用,布局只是调整或
  3. 将应用限制为仅纵向,以免调用 onCreate

【问题讨论】:

  • this blog post中也有关于如何在activity配置更改期间保留长时间运行的异步任务的比较完整的解释!
  • 这不是其他人已经回答的直接答案,但我邀请您查看LogLifeCycle 以了解您的 Android 应用程序在生命周期方面发生了什么。

标签: android rotation android-activity


【解决方案1】:

使用应用程序类

根据您在初始化中所做的工作,您可以考虑创建一个扩展 Application 的新类,并将您的初始化代码移动到该类中被覆盖的 onCreate 方法中。

public class MyApplicationClass extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // TODO Put your application initialization code here.
  }
}

应用程序类中的onCreate仅在整个应用程序创建时被调用,因此Activity在方向重启或键盘可见性变化时不会触发它。

最好将此类的实例公开为单例,并使用 getter 和 setter 公开您正在初始化的应用程序变量。

注意:您需要在清单中指定新应用程序类的名称才能注册和使用它:

<application
    android:name="com.you.yourapp.MyApplicationClass"

对配置更改做出反应 [更新:自 API 13 起已弃用; see the recommended alternative]

作为另一种选择,您可以让应用程序侦听可能导致重启的事件(例如方向和键盘可见性更改)并在 Activity 中处理它们。

首先将 android:configChanges 节点添加到 Activity 的清单节点

 <activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

Android 3.2 (API level 13) and newer

<activity android:name=".MyActivity"
      android:configChanges="keyboardHidden|orientation|screenSize"
      android:label="@string/app_name">

然后在 Activity 中重写 onConfigurationChanged 方法并调用 setContentView 以强制在新方向上重新完成 GUI 布局。

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}

【讨论】:

  • 我认为第二种方法行不通。我尝试过这个;一个带有 EditText 的 Activity。我在那里写了一些文字,改变方向,文字消失/重置。
  • 希望我们将来能看到 onRotate() 方法。甚至不得不担心这样的事情——坦率地说——令人沮丧。
  • 请注意,the Android Dev Guide 警告不要使用它:注意:应避免使用 (android:configChanges),并且仅将其用作最后的手段。有关如何正确处理由于配置更改而重新启动的更多信息,请阅读处理运行时更改。 作为替代,为了在轮换事件中保留数据,他们似乎更喜欢使用 onSaveInstanceState Bundle;或@Jon-O mentions, onRetainNonConfigurationInstance
  • 我认为您应该将this update on 3.2 添加到您的答案中,这非常重要(刚刚遇到这个问题)并且可能会被忽略。
  • 使用android:configChanges 为我节省了大量的工作,所以当谷歌告诉我只将它用作最后手段而不解释为什么时,我讨厌它。给我一个不节省大量工作的理由。请。
【解决方案2】:

Android 3.2 及更高版本的更新:

警告:从 Android 3.2(API 级别 13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。因此,如果您希望在针对 API 级别 13 或更高级别(由 minSdkVersion 和 targetSdkVersion 属性声明)进行开发时防止由于方向更改而导致运行时重新启动,则除了 "orientation" 值之外,您还必须包含 "screenSize" 值。也就是说,您必须声明android:configChanges="orientation|screenSize"。但是,如果您的应用程序以 API 级别 12 或更低级别为目标,那么您的 Activity 始终会自行处理此配置更改(此配置更改不会重新启动您的 Activity,即使在 Android 3.2 或更高版本的设备上运行时也是如此)。

【讨论】:

  • 感谢您的澄清,因为上面对此的评论几乎让我去调查它。我目前的目标是 API 8,我的代码在 configChanges 上没有 screenSize,并且可以确认它在我拥有的运行 ICS 的设备上工作正常(无需重新定向)。
  • 感谢您指出这一点,我只设置了 android:configChanges="orientation|screenSize" ,并且方向切换正在重新创建我的 Activity,而对于我的一生,我无法弄清楚为什么!
  • 添加 android:configChanges 只能作为最后的手段。考虑改用FragmentssetRetainInstance
  • 关键是screenSize for Android 3.2 及更高版本,解决了我的问题,谢谢!
【解决方案3】:

与其尝试完全阻止onCreate() 被触发,不如尝试检查传递给事件的Bundle savedInstanceState 以查看它是否为空。

例如,如果我有一些逻辑应该在真正创建 Activity 时运行,而不是在每次方向更改时运行,我只在 onCreate() 为空时才在 onCreate() 中运行该逻辑。

否则,我仍然希望布局正确重绘以适应方向。

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

        if(savedInstanceState == null){
            setupCloudMessaging();
        }
}

不确定这是否是最终答案,但它对我有用。

【讨论】:

  • 你在哪里保存状态?
  • 这似乎对我有用,而且它似乎是迄今为止最简单的方法。我注意到你只得到了 4 个 ups(包括我的 5 个)与 373 个关于子类化应用程序的想法,在我看来,这似乎要复杂得多。这种方法有什么缺点吗?
  • 这个解决方案对我来说非常有用。我能够Intent serverintent = new Intent(MainActivity.this, MessageListener.class);startService(serverintent); 使用BufferedReader(new InputStreamReader(client.getInputStream())); 创建serverSocket = new ServerSocket(0xcff2);Socket client = serverSocket.accept();,并且可以旋转我的android 并保持客户端/服务器连接处于活动状态,但让GUI 旋转。根据手册,当最后一个活动关闭时,savedInstanceState 会被初始化。
  • 我不明白,有什么问题?这很有效,而且比任何其他解决方案的复杂性都要低。
  • 这是在 Android 中正确的做法。基本上用 configChanges 来捕捉旋转的其他方法以及所有笨重、复杂和不必要的方法。
【解决方案4】:

我做了什么……

在清单中的活动部分,添加:

android:configChanges="keyboardHidden|orientation"

在活动代码中,已实现:

//used in onCreate() and onConfigurationChanged() to set up the UI elements
public void InitializeUI()
{
    //get views from ID's
    this.textViewHeaderMainMessage = (TextView) this.findViewById(R.id.TextViewHeaderMainMessage);

    //etc... hook up click listeners, whatever you need from the Views
}

//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    InitializeUI();
}

//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
    super.onConfigurationChanged(newConfig);
    setContentView(R.layout.main);

    InitializeUI();
}

【讨论】:

  • 澄清一下:通过我的实现,您现在可以在 onCreate() 中进行变量初始化,并且只会调用 onConfigurationChanged() 来进行屏幕旋转。您的变量现在不受屏幕旋转的影响;-) nice 和 ez
  • 我按照这里的描述做了所有事情,但是当我在方向改变后尝试按下按钮时得到 NullPointerException。有什么问题?
  • 请记住,我的回答就像 3 岁,Android 不断发展......西蒙 - 你有示例代码的链接吗?这就是人们所需要的。
  • 当警告 android:configChanges 时,@SimonAndréForsberg 实际上只是在解释Android docsHandling Runtime Changes 有更详细的替代信息(包括示例代码)。
【解决方案5】:

您所描述的是默认行为。您必须自己检测和处理这些事件,方法是添加:

android:configChanges

到您的清单,然后是您要处理的更改。所以对于方向,你会使用:

android:configChanges="orientation"

对于打开或关闭的键盘,您将使用:

android:configChanges="keyboardHidden"

如果你想同时处理这两种情况,你可以使用管道命令将它们分开,例如:

android:configChanges="keyboardHidden|orientation"

这将在您调用的任何 Activity 中触发 onConfigurationChanged 方法。如果您覆盖该方法,则可以传入新值。

希望这会有所帮助。

【讨论】:

  • @GregD 我知道,这就是为什么现在是更新它以反映当今情况的好时机。考虑到这个问题的投票数量,它仍然被其他关于 SO 的问题所引用。
【解决方案6】:

我刚刚发现了这个传说:

为了通过方向更改保持活动活动,并通过onConfigurationChangedthe documentationthe code sample above 处理它,建议在清单文件中这样做:

<activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

它还有一个额外的好处,那就是它总是有效的。

额外的知识是省略keyboardHidden 可能看起来合乎逻辑,但它会导致模拟器失败(至少对于Android 2.1):仅指定orientation 将使模拟器同时调用OnCreateonConfigurationChanged有时,只有OnCreate 其他时候。

我没有在设备上看到失败,但我听说过其他人的模拟器失败。所以值得记录。

【讨论】:

  • 警告:从 Android 3.2(API 级别 13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。因此,如果您想在为 API 级别 13 或更高级别进行开发时防止由于方向更改而导致运行时重新启动:android:configChanges="orientation|keyboardHidden|screenSize"
【解决方案7】:

您也可以考虑使用 Android 平台的跨方向更改持久化数据的方式:onRetainNonConfigurationInstance()getLastNonConfigurationInstance()

这使您可以跨配置更改保留数据,例如您可能从服务器获取的信息或在onCreate 或之后计算的其他信息,同时还允许 Android 使用重新布局您的 Activity正在使用的方向的 xml 文件。

请参阅herehere

应该注意的是,这些方法现在已被弃用(尽管仍然比大多数上述解决方案建议的自己处理方向更改更灵活),建议每个人都切换到Fragments,而不是在每个@上使用setRetainInstance(true) 987654329@你想保留。

【讨论】:

  • 我真的认为 Fragments 和 setRetainInstance 是执行此操作的最佳方式(也是 Google 推荐的方式),对您 +1,对所有其他人 -1。添加 android:configChanges 只能作为最后的手段
【解决方案8】:

该方法很有用,但在使用 Fragments 时不完整。

片段通常会在配置更改时重新创建。如果您不希望发生这种情况,请使用

片段构造函数中的setRetainInstance(true);

这将导致在配置更改期间保留片段。

http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)

【讨论】:

  • 同意。使用最新的 Android API,片段似乎是处理此问题的正确方法。我自己还没有尝试过,但是根据我收集到的阅读this page 的内容,您基本上将过去在 Activity 中实现的 99% 移动到 Fragment 的子类中,然后将该 Fragment 添加到 Activity 中。 Activity 仍将在屏幕旋转时被销毁并重新创建,但您可以明确告诉 androidnot 使用 @Abdo 提到的 setRetainInstance() 方法销毁 Fragment。
【解决方案9】:

我只是简单地添加了

     android:configChanges="keyboard|keyboardHidden|orientation"

在清单文件中并且没有在我的活动中添加任何onConfigurationChanged 方法。

So every time the keyboard slides out or in nothing happens.

【讨论】:

    【解决方案10】:

    即使你改变了android的orientationonCreate方法仍然被调用。因此,将所有繁重的功能移至此方法对您没有帮助

    【讨论】:

      【解决方案11】:

      将下面的代码放在Manifest.xml 中的&lt;activity&gt; 标记中:

      android:configChanges="screenLayout|screenSize|orientation"
      

      【讨论】:

        【解决方案12】:

        这很简单,只需执行以下步骤:

        <activity
            android:name=".Test"
            android:configChanges="orientation|screenSize"
            android:screenOrientation="landscape" >
        </activity>
        

        这对我有用:

        注意:方向取决于您的要求

        【讨论】:

          【解决方案13】:
           onConfigurationChanged is called when the screen rotates. 
           (onCreate is no longer called when screen rotates due to manifest, see:  
           android:configChanges)
          

          清单的哪一部分告诉它“不要调用onCreate()”?

          另外, 谷歌的文档说要避免使用android:configChanges(除非作为最后的手段)......但是他们建议所有的替代方法DO使用android:configChanges

          根据我的经验,模拟器在轮换时总是调用onCreate()
          但是我在上面运行相同代码的 1-2 台设备……没有。 (不知道为什么会有任何区别。)

          【讨论】:

            【解决方案14】:

            要在 Android 清单中进行的更改是:

            android:configChanges="keyboardHidden|orientation" 
            

            要在活动中添加的内容是:

            public void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
            
                // Checks the orientation of the screen
                if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
                } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                    Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
                }
            }
            

            【讨论】:

              【解决方案15】:

              将此行添加到您的清单中:-

              android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"
              

              这个sn-p到活动:-

              @Override
                  public void onConfigurationChanged(Configuration newConfig) {
                      super.onConfigurationChanged(newConfig);
                      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                              WindowManager.LayoutParams.FLAG_FULLSCREEN);
                  }
              

              【讨论】:

                【解决方案16】:

                有几种方法可以做到这一点:

                保存活动状态

                您可以将活动状态保存在onSaveInstanceState

                @Override
                public void onSaveInstanceState(Bundle outState) {
                    /*Save your data to be restored here
                    Example : outState.putLong("time_state", time); , time is a long variable*/
                    super.onSaveInstanceState(outState);
                }
                

                然后使用bundle恢复状态。

                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                
                    if(savedInstanceState!= null){
                       /*When rotation occurs
                        Example : time = savedInstanceState.getLong("time_state", 0); */
                    } else {
                      //When onCreate is called for the first time
                    }
                }
                

                自行处理方向变化

                另一种选择是自己处理方向变化。但这不是一个好的做法。

                将此添加到您的清单文件中。

                android:configChanges="keyboardHidden|orientation"
                

                适用于 Android 3.2 及更高版本:

                android:configChanges="keyboardHidden|orientation|screenSize"
                
                @Override
                public void onConfigurationChanged(Configuration config) {
                    super.onConfigurationChanged(config);
                
                if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                        //Handle rotation from landscape to portarit mode here
                    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
                        //Handle rotation from portrait to landscape mode here
                    }
                }
                

                限制旋转

                您还可以将活动限制为纵向或横向模式以避免旋转。

                将此添加到清单文件中的活动标记中:

                        android:screenOrientation="portrait"
                

                或在您的活动中以编程方式实现:

                @Override
                    protected void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);
                        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                }
                

                【讨论】:

                  【解决方案17】:

                  我发现这样做的方法是使用onRestoreInstanceStateonSaveInstanceState 事件在Bundle 中保存一些东西(即使您不需要保存任何变量,只需在其中放一些东西,这样@987654324 @ 不为空)。然后,在onCreate方法上,查看Bundle是否为空,如果是,则进行初始化,如果不是,则进行。

                  【讨论】:

                    【解决方案18】:

                    尽管它不是“Android 方式”,但我通过自己处理方向更改并简单地在视图中重新定位小部件以将更改的方向考虑在内,获得了非常好的结果。这比任何其他方法都快,因为您的视图不必保存和恢复。它还为用户提供了更无缝的体验,因为重新定位的小部件是完全相同的小部件,只是移动和/或调整大小。通过这种方式不仅可以保存模型状态,还可以保存视图状态。

                    RelativeLayout 有时对于必须不时重新定位自身的视图来说是一个不错的选择。您只需为每个子小部件提供一组纵向布局参数和一组横向布局参数,每个参数具有不同的相对定位规则。然后,在您的onConfigurationChanged() 方法中,将适当的方法传递给每个孩子的setLayoutParams() 调用。如果任何子控件本身需要在内部重新定向,您只需调用该子控件的方法来执行重新定向。该子控件类似地调用任何子控件上的方法,这些控件需要内部重新定向,等等。

                    【讨论】:

                    • 我很想看看这个示例代码,看起来很棒!
                    【解决方案19】:

                    每次旋转屏幕时,打开的活动都结束并再次调用 onCreate()。

                    1 .当屏幕旋转时,您可以做一件事来保存活动的状态,以便在再次调用活动的 onCreate() 时恢复所有旧的东西。 参考this链接

                    2 。如果您想防止重新启动活动,只需在 manifest.xml 文件中添加以下行。

                      <activity android:name=".Youractivity"
                      android:configChanges="orientation|screenSize"/>
                    

                    【讨论】:

                      【解决方案20】:

                      您需要使用 onSavedInstanceState 方法将所有值存储到它的参数 is has that is bundle

                      @Override
                          public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
                              super.onSaveInstanceState(outState, outPersistentState);
                              outPersistentState.putBoolean("key",value);
                          }
                      

                      并使用

                      @Override
                          protected void onRestoreInstanceState(Bundle savedInstanceState) {
                              super.onRestoreInstanceState(savedInstanceState);
                              savedInstanceState.getBoolean("key");
                          } 
                      

                      检索并设置值以查看对象 它将处理屏幕旋转

                      【讨论】:

                        【解决方案21】:

                        注意:如果将来有人遇到与我相同的问题,我会发布此答案。对我来说,以下行是不够的:

                        android:configChanges="orientation"
                        

                        当我旋转屏幕时,`onConfigurationChanged(Configuration newConfig) 方法没有被调用。

                        解决方案:即使问题与方向有关,我也必须添加“screenSize”。所以在 AndroidManifest.xml - 文件中,添加:

                        android:configChanges="keyboardHidden|orientation|screenSize"
                        

                        然后实现方法onConfigurationChanged(Configuration newConfig)

                        【讨论】:

                          【解决方案22】:

                          manifest的活动部分,添加:

                          android:configChanges="keyboardHidden|orientation"
                          

                          【讨论】:

                            【解决方案23】:

                            在清单中添加这一行: android:configChanges="orientation|screenSize"

                            【讨论】:

                              【解决方案24】:

                              人们说你应该使用

                              android:configChanges="keyboardHidden|orientation"
                              

                              但在 Android 中处理旋转的最好和最专业的方法是使用 Loader 类。它不是一个著名的类(我不知道为什么),但它比 AsyncTask 好得多。有关更多信息,您可以阅读 Udacity 的 Android 课程中的 Android 教程。

                              当然,作为另一种方式,您可以使用 onSaveInstanceState 存储值或视图,并使用 onRestoreInstanceState 读取它们。这真的取决于你。

                              【讨论】:

                              • 是的,让我们添加一些额外的代码以看起来“专业”。或者,如何坚持使用 configurationChanges 属性快速、简单、真实且经过尝试的方式。
                              【解决方案25】:

                              谷歌推出的最好的android架构组件之一将满足您对ViewModel的所有要求。

                              旨在以生命周期的方式存储和管理与 UI 相关的数据,并且允许数据在屏幕旋转时存活

                              class MyViewModel : ViewModel() {
                              

                              请参考:https://developer.android.com/topic/libraries/architecture/viewmodel

                              【讨论】:

                                【解决方案26】:

                                经过一段时间的反复试验,我找到了一个在大多数情况下都能满足我需求的解决方案。这是代码:

                                清单配置:

                                <?xml version="1.0" encoding="utf-8"?>
                                <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                                          package="com.pepperonas.myapplication">
                                
                                    <application
                                        android:name=".App"
                                        android:allowBackup="true"
                                        android:icon="@mipmap/ic_launcher"
                                        android:label="@string/app_name"
                                        android:supportsRtl="true"
                                        android:theme="@style/AppTheme">
                                        <activity
                                            android:name=".MainActivity"
                                            android:configChanges="orientation|keyboardHidden|screenSize">
                                            <intent-filter>
                                                <action android:name="android.intent.action.MAIN"/>
                                
                                                <category android:name="android.intent.category.LAUNCHER"/>
                                            </intent-filter>
                                        </activity>
                                    </application>
                                
                                </manifest>
                                

                                MainActivity:

                                import android.content.res.Configuration;
                                import android.os.Bundle;
                                import android.support.v4.app.Fragment;
                                import android.support.v4.app.FragmentManager;
                                import android.support.v4.app.FragmentTransaction;
                                import android.support.v7.app.AppCompatActivity;
                                import android.util.Log;
                                import android.view.View;
                                import android.widget.Button;
                                
                                public class MainActivity extends AppCompatActivity implements View.OnClickListener {
                                
                                    private static final String TAG = "MainActivity";
                                
                                    private Fragment mFragment;
                                
                                    private int mSelected = -1;
                                
                                
                                    @Override
                                    public void onCreate(Bundle savedInstanceState) {
                                        super.onCreate(savedInstanceState);
                                        Log.d(TAG, "onCreate  " + "");
                                
                                        // null check not realy needed - but just in case...
                                        if (savedInstanceState == null) {
                                
                                            initUi();
                                
                                            // get an instance of FragmentTransaction from your Activity
                                            FragmentManager fragmentManager = getSupportFragmentManager();
                                            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                                
                                            /*IMPORTANT: Do the INITIAL(!) transaction only once!
                                            * If we call this everytime the layout changes orientation,
                                            * we will end with a messy, half-working UI.
                                            * */
                                            mFragment = FragmentOne.newInstance(mSelected = 0);
                                            fragmentTransaction.add(R.id.frame, mFragment);
                                            fragmentTransaction.commit();
                                        }
                                    }
                                
                                
                                    @Override
                                    public void onConfigurationChanged(Configuration newConfig) {
                                        super.onConfigurationChanged(newConfig);
                                        Log.d(TAG, "onConfigurationChanged  " +
                                                   (newConfig.orientation
                                                    == Configuration.ORIENTATION_LANDSCAPE
                                                    ? "landscape" : "portrait"));
                                
                                        initUi();
                                
                                        Log.i(TAG, "onConfigurationChanged - last selected: " + mSelected);
                                        makeFragmentTransaction(mSelected);
                                    }
                                
                                
                                    /**
                                     * Called from {@link #onCreate} and {@link #onConfigurationChanged}
                                     */
                                    private void initUi() {
                                        setContentView(R.layout.activity_main);
                                        Log.d(TAG, "onCreate  instanceState == null / reinitializing..." + "");
                                        Button btnFragmentOne = (Button) findViewById(R.id.btn_fragment_one);
                                        Button btnFragmentTwo = (Button) findViewById(R.id.btn_fragment_two);
                                        btnFragmentOne.setOnClickListener(this);
                                        btnFragmentTwo.setOnClickListener(this);
                                    }
                                
                                
                                    /**
                                     * Not invoked (just for testing)...
                                     */
                                    @Override
                                    protected void onSaveInstanceState(Bundle outState) {
                                        super.onSaveInstanceState(outState);
                                        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME!!!");
                                    }
                                
                                
                                    /**
                                     * Not invoked (just for testing)...
                                     */
                                    @Override
                                    protected void onRestoreInstanceState(Bundle savedInstanceState) {
                                        super.onRestoreInstanceState(savedInstanceState);
                                        Log.d(TAG, "onSaveInstanceState  " + "YOU WON'T SEE ME, AS WELL!!!");
                                    }
                                
                                
                                    @Override
                                    protected void onResume() {
                                        super.onResume();
                                        Log.d(TAG, "onResume  " + "");
                                    }
                                
                                
                                    @Override
                                    protected void onPause() {
                                        super.onPause();
                                        Log.d(TAG, "onPause  " + "");
                                    }
                                
                                
                                    @Override
                                    protected void onDestroy() {
                                        super.onDestroy();
                                        Log.d(TAG, "onDestroy  " + "");
                                    }
                                
                                
                                    @Override
                                    public void onClick(View v) {
                                
                                        switch (v.getId()) {
                                            case R.id.btn_fragment_one:
                                                Log.d(TAG, "onClick btn_fragment_one " + "");
                                                makeFragmentTransaction(0);
                                                break;
                                
                                            case R.id.btn_fragment_two:
                                                Log.d(TAG, "onClick btn_fragment_two " + "");
                                                makeFragmentTransaction(1);
                                                break;
                                
                                            default:
                                                Log.d(TAG, "onClick  null - wtf?!" + "");
                                        }
                                    }
                                
                                
                                    /**
                                     * We replace the current Fragment with the selected one.
                                     * Note: It's called from {@link #onConfigurationChanged} as well.
                                     */
                                    private void makeFragmentTransaction(int selection) {
                                
                                        switch (selection) {
                                            case 0:
                                                mFragment = FragmentOne.newInstance(mSelected = 0);
                                                break;
                                            case 1:
                                                mFragment = FragmentTwo.newInstance(mSelected = 1);
                                                break;
                                        }
                                
                                        // Create new transaction
                                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                                
                                        // Replace whatever is in the fragment_container view with this fragment,
                                        // and add the transaction to the back stack
                                        transaction.replace(R.id.frame, mFragment);
                                
                                        /*This would add the Fragment to the backstack...
                                        * But right now we comment it out.*/
                                        //        transaction.addToBackStack(null);
                                
                                        // Commit the transaction
                                        transaction.commit();
                                    }
                                
                                }
                                

                                和示例片段:

                                import android.os.Bundle;
                                import android.support.v4.app.Fragment;
                                import android.util.Log;
                                import android.view.LayoutInflater;
                                import android.view.View;
                                import android.view.ViewGroup;
                                
                                /**
                                 * @author Martin Pfeffer (pepperonas)
                                 */
                                public class FragmentOne extends Fragment {
                                
                                    private static final String TAG = "FragmentOne";
                                
                                
                                    public static Fragment newInstance(int i) {
                                        Fragment fragment = new FragmentOne();
                                        Bundle args = new Bundle();
                                        args.putInt("the_id", i);
                                        fragment.setArguments(args);
                                        return fragment;
                                    }
                                
                                
                                    @Override
                                    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                                        Log.d(TAG, "onCreateView  " + "");
                                        return inflater.inflate(R.layout.fragment_one, container, false);
                                    }
                                
                                }
                                

                                可以在github找到。

                                【讨论】:

                                  【解决方案27】:

                                  使用orientation监听器在不同的方向上执行不同的任务。

                                  @Override
                                  public void onConfigurationChanged(Configuration myConfig) 
                                  {
                                      super.onConfigurationChanged(myConfig);
                                      int orient = getResources().getConfiguration().orientation; 
                                      switch(orient) 
                                      {
                                         case Configuration.ORIENTATION_LANDSCAPE:
                                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                                                      break;
                                         case Configuration.ORIENTATION_PORTRAIT:
                                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                                                      break;
                                         default:
                                            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
                                      }
                                  }
                                  

                                  【讨论】:

                                    【解决方案28】:

                                    将下面的代码放入您的ActivityAndroid Manifest

                                    android:configChanges="orientation"
                                    

                                    当您改变方向时,这不会重新启动您的活动。

                                    【讨论】:

                                    • @Mavamaarten 可能是因为正如其他人所指出的那样,这是一种不好的做法,其他十个答案已经涵盖了这一点。
                                    【解决方案29】:

                                    修复AndroidManifest.xml中的屏幕方向(横向或纵向)

                                    android:screenOrientation="portrait"android:screenOrientation="landscape"

                                    为此,您的 onResume() 方法未被调用。

                                    【讨论】:

                                    • 如何解决问题是一个答案?如果我们锁定使用它的用户,为什么我们的设备会旋转?
                                    【解决方案30】:

                                    您可以在活动中使用 ViewModel 对象。

                                    ViewModel 对象在配置更改期间会自动保留,以便它们保存的数据可立即用于下一个活动或片段实例。 阅读更多:

                                    https://developer.android.com/topic/libraries/architecture/viewmodel

                                    【讨论】:

                                      猜你喜欢
                                      • 1970-01-01
                                      • 2011-08-24
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      相关资源
                                      最近更新 更多