ChatGPT解决这个技术问题 Extra ChatGPT

旋转Android上的活动重启

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

将所有初始设置放在另一个函数中,这样它就不会在设备旋转时全部丢失或 Make it so onCreate 不会再次调用并且布局只是调整或将应用程序限制为仅纵向以便不会调用 onCreate 。

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

K
Kaleem

使用应用程序类

根据您在初始化中所做的事情,您可以考虑创建一个扩展 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 mentionsonRetainNonConfigurationInstance
我认为您应该将 this update on 3.2 添加到您的答案中,这非常重要(刚刚遇到这个问题)并且可能会被忽略。
使用 android:configChanges 为我节省了大量工作,因此当 Google 告诉我仅将其用作最后手段而没有解释为什么时,我讨厌它。给我一个不节省大量工作的理由。请。
G
Gorm

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" ,并且方向切换正在重新创建我的活动,而对于我的生活,我无法弄清楚为什么!
添加 android:configChanges 只能作为最后的手段。请考虑改用 FragmentssetRetainInstance
Android 3.2 及更高版本的关键点是screenSize,它解决了我的问题,谢谢!
n
nebulae

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

例如,如果我有一些逻辑应该在真正创建 Activity 时运行,而不是在每次方向更改时运行,我只在 savedInstanceState 为空时才在 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 来捕捉旋转的其他方法以及所有笨重、复杂和不必要的方法。
S
Someone Somewhere

我做了什么...

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

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 包含有关替代方案的更详细信息(包括示例代码)。
G
GregD

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

android:configChanges

到您的清单,然后是您要处理的更改。因此,对于方向,您将使用:

android:configChanges="orientation"

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

android:configChanges="keyboardHidden"

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

android:configChanges="keyboardHidden|orientation"

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

希望这可以帮助。


@GregD 我知道,这就是为什么现在是更新它以反映当今情况的好时机。鉴于这个问题的赞成票数量,它仍然被其他关于 SO 的问题所引用。
K
Kaleem

我刚刚发现了这个传说:

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

<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"
J
Jon O

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

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

请参阅 herehere

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


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

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

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

setRetainInstance(true); 在 Fragment 的构造函数中

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

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


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

我只是简单地添加了

     android:configChanges="keyboard|keyboardHidden|orientation"

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

So every time the keyboard slides out or in nothing happens


P
Piyush

即使您更改了 android 的 orientation,仍然会调用 onCreate 方法。因此,将所有繁重的功能移至此方法不会对您有所帮助


P
Praveen

将以下代码放入 Manifest.xml 中的 <activity> 标记内:

android:configChanges="screenLayout|screenSize|orientation"

B
Ben Thomas

非常简单,只需执行以下步骤:

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

这对我有用:

注意:方向取决于您的回报


R
Ramesh R
onConfigurationChanged is called when the screen rotates. 
(onCreate is no longer called when the screen rotates due to manifest, see:  
android:configChanges)

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

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

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


M
Mark Bell

在 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();
    }
}

P
Pratik Butani

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

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

和这个活动片段:-

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

P
Piyush

做这件事有很多种方法:

保存活动状态

您可以将活动状态保存在 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);
}

C
Catalina

我发现这样做的方法是使用 onRestoreInstanceStateonSaveInstanceState 事件将某些内容保存在 Bundle 中(即使您不需要保存任何变量,只需将某些内容放在那里,这样 Bundle 就不会t 为空)。然后,在onCreate方法上,检查Bundle是否为空,如果是,则进行初始化,如果不是,则进行初始化。


r
ra1ned

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

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


我很想看到一些示例代码,看起来很棒!
R
Ramesh R

每次旋转屏幕时,打开的 Activity 都会完成并再次调用 onCreate()。

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

2.如果您想阻止重新启动活动,只需将以下行放在您的 manifest.xml 文件中。

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

R
Ramesh R

您需要使用 onSavedInstanceState 方法将所有值存储到其参数 is has 这是一个包

@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");
    } 

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


R
Ramesh R

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

android:configChanges="orientation"

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

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

android:configChanges="keyboardHidden|orientation|screenSize"

然后实现方法 onConfigurationChanged(Configuration newConfig)


J
Justin

manifest 的活动部分中,添加:

android:configChanges="keyboardHidden|orientation"

A
Agilanbu

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


T
Theo

人们说你应该使用

android:configChanges="keyboardHidden|orientation"

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

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


是的,让我们添加一些额外的代码来看起来“专业”。或者,如何坚持使用 configurationChanges 属性快速、简单、真实且经过尝试的方法。
R
Ramesh R

谷歌引入的最好的 android 架构组件之一将满足 ViewModel 的所有要求。

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

class MyViewModel : ViewModel() {

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


M
Martin Pfeffer

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

清单配置:

<?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>

主要活动:

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 上找到。


P
Piyush

使用 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);
    }
}

P
Piyush

将以下代码放入 Android Manifest 中的 Activity

android:configChanges="orientation"

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


@Mavamaarten 可能是因为正如其他人所指出的那样,这是不好的做法,其他十个答案已经涵盖了这一点。
P
Piyush

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

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

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


到底如何解决问题是一个答案?如果我们锁定使用它的用户,为什么我们的设备会旋转?
R
Ramesh R

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

ViewModel 对象在配置更改期间自动保留,以便它们保存的数据可立即用于下一个活动或片段实例。阅读更多:https://developer.android.com/topic/libraries/architecture/viewmodel