В моем приложении для Android, когда я поворачиваю устройство (выдвигая клавиатуру), мой Activity перезапускается (вызывается onCreate). Вероятно, так оно и должно быть, но я много выполняю первоначальную настройку с помощью метода onCreate, поэтому мне нужно либо:
onCreate не вызывался снова, а макет просто настраивался илиonCreate.Это не прямой ответ, поскольку другие уже ответили, но я предлагаю вам взглянуть на LogLifeCycle, чтобы понять, что происходит в ваших приложениях для Android в отношении жизненных циклов.
Вы описываете поведение по умолчанию. Вы должны сами обнаруживать и обрабатывать эти события, добавляя:
android:configChanges
в ваш манифест, а затем изменения, которые вы хотите обработать. Итак, для ориентации вы должны использовать:
android:configChanges = "orientation"
а для открывающейся или закрывающейся клавиатуры вы должны использовать:
android:configChanges = "keyboardHidden"
Если вы хотите обрабатывать и то, и другое, вы можете просто разделить их с помощью команды конвейера, например:
android:configChanges = "keyboardHidden|orientation"
Это вызовет запуск метода onConfigurationChanged в любом действии, которое вы вызываете. Если вы переопределите метод, вы можете передать новые значения.
Надеюсь это поможет.
@GregD Я знаю, поэтому сейчас хорошее время обновить его, чтобы отразить сегодняшнюю ситуацию. Учитывая количество голосов за этот вопрос, на него по-прежнему ссылаются из других вопросов по SO.
Использование класса приложения
В зависимости от того, что вы делаете при инициализации, вы можете рассмотреть возможность создания нового класса, расширяющего Application, и переноса кода инициализации в переопределенный метод onCreate внутри этого класса.
public class MyApplicationClass extends Application {
@Override
public void onCreate() {
super.onCreate();
// TODO Put your application initialization code here.
}
}
onCreate в классе приложения вызывается только при создании всего приложения, поэтому действие перезапускается при изменении ориентации или видимости клавиатуры не запускается.
Хорошей практикой является предоставление экземпляра этого класса как синглтона и предоставление переменных приложения, которые вы инициализируете, с помощью методов получения и установки.
ПРИМЕЧАНИЕ. Вам нужно будет указать имя вашего нового класса Application в манифесте, чтобы его можно было зарегистрировать и использовать:
<application
android:name = "com.you.yourapp.MyApplicationClass"
Реакция на изменения конфигурации[ОБНОВЛЕНИЕ: это устарело с API 13; см. рекомендованную альтернативу]
В качестве дополнительной альтернативы вы можете настроить ваше приложение на прослушивание событий, которые могут вызвать перезапуск, например, изменения ориентации и видимости клавиатуры, и обрабатывать их в вашей Activity.
Начните с добавления узла android:configChanges в узел манифеста вашей деятельности.
<activity android:name = ".MyActivity"
android:configChanges = "orientation|keyboardHidden"
android:label = "@string/app_name">
или для Android 3.2 (уровень API 13) и новее:
<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. Я написал там какой-то текст, сменил ориентацию, и текст пропал / сбросился.
Надеемся, что в будущем мы увидим метод onRotate (). Честно говоря, необходимость даже беспокоиться о таких вещах расстраивает.
Не забывайте keyboardHidden в android:configChanges. Я это сделал, и это все равно привело к уничтожению и воссозданию активности.
Обратите внимание, что Руководство разработчика Android предостерегает от использования этого: Примечание. Следует избегать использования (android:configChanges) и использовать его только в крайнем случае. Пожалуйста, прочтите «Обработка изменений во время выполнения» для получения дополнительной информации о том, как правильно обрабатывать перезапуск из-за изменения конфигурации. Вместо того, чтобы сохранять данные в событиях вращения, они, кажется, предпочитают использовать onSaveInstanceState Bundle; или как @ Jon-O упоминает, onRetainNonConfigurationInstance.
Это плохое решение, потому что оно реагирует только на изменения конфигурации в настоящее время известно. В более новых версиях Android могут произойти другие изменения конфигурации, которые этот код не улавливает (поскольку он должен перечислять все изменения конфигурации в манифесте). Решение сохранения состояния с помощью onRetainNonConfigurationChanges более отказоустойчивое и простое.
Я думаю, вам следует добавить к своему ответу это обновление 3.2, это очень важно (только что столкнулся с этой проблемой), и это может быть упущено из виду.
Использование android:configChanges избавляет меня от кучи работы, поэтому я ненавижу, когда Google говорит мне использовать его только в крайнем случае, не объясняя Зачем. Дайте мне повод не экономить кучу работы. Пожалуйста.
Google говорит не использовать android:configChanges, потому что: Самостоятельная обработка изменений конфигурации может значительно затруднить использование альтернативных ресурсов, поскольку система не применяет их автоматически.источник Кажется разумным предотвратить портрет / пейзаж с этим, поскольку вы говорите, что не хотите, чтобы он обрабатывался вообще. Предостережение: я android n00b.
В последнем коде не используйте setContentView. Он будет работать правильно.
Метод onCreate по-прежнему вызывается даже при смене orientation в android. Так что перенос всей тяжелой функциональности на этот метод вам не поможет.
Я только что открыл для себя эти знания:
Для сохранения активности посредством изменения ориентации и обработки ее через onConfigurationChanged, документация и пример кода выше предложите это в файле манифеста:
<activity android:name = ".MyActivity"
android:configChanges = "orientation|keyboardHidden"
android:label = "@string/app_name">
который имеет дополнительное преимущество в том, что он всегда работает.
Бонусом является то, что пропуск keyboardHidden может показаться логичным, но он вызывает сбои в эмуляторе (по крайней мере, для Android 2.1): указание только orientation заставит эмулятор иногда вызывать и OnCreate, и onConfigurationChanged, а в других случаях только OnCreate.
Я не видел сбоев на одном устройстве, но слышал о сбоях эмулятора у других. Так что это стоит задокументировать.
Внимание! Начиная с Android 3.2 (уровень API 13), «размер экрана» также изменяется при переключении устройства между книжной и альбомной ориентацией. Таким образом, если вы хотите предотвратить перезапуск среды выполнения из-за изменения ориентации при разработке для уровня API 13 или выше: android: configChanges = "direction | keyboardHidden | screenSize"
что я сделал...
в манифесте, в раздел активности, добавлено:
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 and ez
Я сделал все, как описано здесь, но получаю исключение NullPointerException, когда пытаюсь нажать кнопку после изменения ориентации. Что могло быть не так?
имейте в виду, что моему ответу уже 3 года, а Android продолжает развиваться ... Саймон, у вас есть ссылка на образец кода? Это то, что нужно людям.
В предупреждении против android: configChanges @ SimonAndréForsberg на самом деле просто перефразирует Документы для Android. Обработка изменений среды выполнения содержит более подробную информацию об альтернативах (включая пример кода).
Вы также можете рассмотреть возможность использования платформы Android для сохранения данных при изменении ориентации: onRetainNonConfigurationInstance() и getLastNonConfigurationInstance().
Это позволяет вам сохранять данные при изменении конфигурации, например информацию, которую вы могли получить из выборки с сервера, или что-то еще, что было вычислено в onCreate или с тех пор, а также позволяет Android изменять макет вашего Activity, используя XML-файл для ориентации. в использовании.
Следует отметить, что эти методы теперь устарели (хотя все еще более гибкие, чем изменение ориентации обработки самостоятельно, как предлагают большинство из вышеперечисленных решений) с рекомендацией, чтобы все переключились на Fragments и вместо этого использовали setRetainInstance(true) на каждом Fragment, который вы хотите сохранить.
Я действительно думаю, что Fragments и setRetainInstance - лучший способ (и рекомендованный Google) для этого, +1 вам и -1 всем остальным. Добавление android: configChanges следует использовать только в крайнем случае
В манифест 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();
}
}
onConfigurationChanged is called when the screen rotates. (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
В какой части манифеста сказано «не звонить onCreate()»?
Также,
Документы Google говорят, что следует избегать использования android:configChanges (кроме как в крайнем случае) .... Но тогда альтернативные методы, которые они предлагают, все ДЕЛАТЬ используют android:configChanges.
По моему опыту, эмулятор ВСЕГДА вызывает onCreate() при вращении.
Но 1-2 устройства, на которых я запускаю один и тот же код ... нет.
(Не уверен, почему будет какая-то разница.)
Обновление для Android 3.2 и выше:
Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion and targetSdkVersion attributes), you must include the
"screenSize"value in addition to the"orientation"value. That is, you must declareandroid:configChanges = "orientation|screenSize". However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).
Спасибо за это разъяснение, поскольку вышеприведенный комментарий чуть не отправил меня изучить это. В настоящее время я нацелен на API 8, и в моем коде нет screenSize в configChanges, и я могу подтвердить, что он работает нормально (без переориентации) на моем устройстве, на котором работает ICS.
Спасибо, что указали на это, у меня был установлен только android: configChanges = "Ориентация | screenSize", и переключение ориентации воссоздавало мою активность, и, хоть убей, я не мог понять, почему!
Добавление android: configChanges следует использовать только в крайнем случае. Вместо этого рассмотрите возможность использования Fragments и setRetainInstance.
Ключевым моментом является screenSize для Android 3.2 и выше, который решил мою проблему. Спасибо!
Несмотря на то, что это не «способ Android», я получил очень хорошие результаты, обрабатывая изменения ориентации самостоятельно и просто перемещая виджеты в представлении, чтобы учесть измененную ориентацию. Это быстрее, чем любой другой подход, потому что ваши представления не нужно сохранять и восстанавливать. Это также обеспечивает более плавное взаимодействие с пользователем, поскольку измененные виджеты являются точно такими же виджетами, только что перемещенными и / или измененными в размере. Таким образом можно сохранить не только состояние модели, но и состояние просмотра.
RelativeLayout иногда может быть хорошим выбором для представления, которое время от времени необходимо переориентировать. Вы просто предоставляете набор параметров вертикального макета и набор параметров ландшафтного макета с разными правилами относительного позиционирования для каждого дочернего виджета. Затем в своем методе onConfigurationChanged() вы передаете соответствующий метод вызову setLayoutParams() для каждого дочернего элемента. Если какой-либо дочерний элемент управления должен быть переориентирован внутри, вы просто вызываете метод этого дочернего элемента для выполнения переориентации. Этот дочерний элемент аналогичным образом вызывает методы любого из дочерних элементов управления это, которым требуется внутренняя переориентация, и так далее.
Я хотел бы увидеть пример кода этого, кажется блестящим!
Вместо того, чтобы пытаться полностью остановить срабатывание onCreate(), возможно, попробуйте проверить передаваемый в событие BundlesavedInstanceState, чтобы узнать, является ли он нулевым или нет.
Например, если у меня есть какая-то логика, которая должна выполняться, когда Activity действительно создан, а не при каждом изменении ориентации, я запускаю эту логику в onCreate() только в том случае, если savedInstanceState равен нулю.
В противном случае я все равно хочу, чтобы макет правильно перерисовывался для ориентации.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_list);
if (savedInstanceState == null){
setupCloudMessaging();
}
}
не уверен, что это окончательный ответ, но он работает для меня.
и где ты на самом деле сохраняешь состояние?
это, кажется, работает для меня, и это кажется самым простым методом. Я заметил, что у вас есть только 4 ИБ для этого (5 включая мой) против 373 за идею создания подклассов Application, что мне кажется намного более сложным. Есть ли у этого метода недостатки?
Это решение отлично поработало для меня. Я смог с помощью Intent serverintent = new Intent(MainActivity.this, MessageListener.class); и startService(serverintent); создать serverSocket = new ServerSocket(0xcff2); и Socket client = serverSocket.accept(); с помощью BufferedReader(new InputStreamReader(client.getInputStream())); и мог повернуть свой Android и поддерживать соединение клиент / сервер активным, но при этом повернуть графический интерфейс. Согласно руководству, savedInstanceState инициализируется при завершении последнего действия.
Я не понимаю, в чем прикол? Это отлично работает и с гораздо меньшей сложностью, чем любое другое решение.
Это правильный способ сделать это в Android. Другие способы в основном поймать вращение с помощью configChanges и всего, что громоздко, сложно и ненужно.
Я просто добавил
android:configChanges = "keyboard|keyboardHidden|orientation"
в файле манифеста и не добавил для любого метода onConfigurationChanged в моей деятельности.
Так что каждый раз, когда клавиатура выдвигается, ничего не происходит.
Подход полезен, но неполон при использовании фрагментов.
Обычно фрагменты воссоздаются при изменении конфигурации. Если вы не хотите, чтобы это произошло, используйте
setRetainInstance(true); в конструкторе (ах) фрагмента
Это приведет к сохранению фрагментов во время изменения конфигурации.
http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
Согласовано. С последней версией Android API кажется, что фрагменты - правильный способ справиться с этим. Я сам еще не пробовал, но из того, что я собрал, читая эта страница, вы в основном перемещаете 99% того, что вы использовали для реализации в Activity, в подкласс фрагмента, а затем добавляете этот фрагмент в Activity. Действие по-прежнему будет уничтожено и воссоздано при повороте экрана, но вы можете специально указать Android нет уничтожить фрагмент, используя упомянутый @Abdo метод setRetainInstance().
Я нашел способ сделать это - использовать события onRestoreInstanceState и onSaveInstanceState для сохранения чего-либо в Bundle (даже если вам не нужно сохранять какие-либо переменные, просто поместите что-нибудь туда, чтобы Bundle не был пустым). Затем с помощью метода onCreate проверьте, пуст ли Bundle, и если это так, то выполните инициализацию, если нет, то выполните.
Исправить ориентацию экрана (альбомная или портретная) в AndroidManifest.xml
android:screenOrientation = "portrait" или android:screenOrientation = "landscape"
для этого ваш метод onResume() не вызывается.
как, черт возьми, исправить что-то - это ответ? Почему наши устройства могут вращаться, если мы заблокируем их использование пользователями?
Поместите этот код ниже в свой Activity в Android Manifest.
android:configChanges = "orientation"
Это не приведет к перезапуску вашей деятельности, когда вы измените ориентацию.
@Mavamaarten Вероятно, потому что, как указывали другие, это плохая практика, и десять других ответов уже охватили это.
Примечание: Я отправлю этот ответ, если кто-то в будущем столкнется с той же проблемой, что и я. Мне не хватило следующей строчки:
android:configChanges = "orientation"
Когда я повернул экран, метод onConfigurationChanged (Configuration newConfig) не был вызван.
Решение: Мне также пришлось добавить screenSize, даже если проблема была связана с ориентацией. Итак, в файле AndroidManifest.xml добавьте следующее:
android:configChanges = "keyboardHidden|orientation|screenSize"
Затем реализуйте метод onConfigurationChanged(Configuration newConfig)
Вы можете заблокировать текущую ориентацию экрана с помощью этого кода ...
int currentOrientation =context.getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
((Activity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
((Activity) context). setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
Добавьте эту строку в свой манифест: -
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);
}
Поместите приведенный ниже код в тег <activity> в Manifest.xml:
android:configChanges = "screenLayout|screenSize|orientation"
Используйте прослушиватель 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);
}
}
После некоторого времени проб и ошибок я нашел решение, которое соответствует моим потребностям в большинстве ситуаций. Вот код:
Конфигурация манифеста:
<?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.
Это очень просто, достаточно проделать следующие шаги:
<activity
android:name = ".Test"
android:configChanges = "orientation|screenSize"
android:screenOrientation = "landscape" >
</activity>
Это работает для меня:
Ориентация Примечание: зависит от ваших требований
Есть несколько способов сделать это:
Вы можете сохранить состояние активности в 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);
}
вам нужно использовать метод onSavedInstanceState для хранения всего значения его параметра, которое имеет пакет
@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");
}
получить и установить значение для просмотра объектов он будет обрабатывать поворот экрана
Каждый раз, когда экран поворачивается, открытое действие завершается и onCreate () вызывается снова.
1. Вы можете сделать одну вещь, чтобы сохранить состояние активности при повороте экрана, чтобы вы могли восстановить все старые вещи при повторном вызове активности onCreate (). Обратитесь по ссылке это
2. Если вы хотите предотвратить перезапуск активности, просто поместите следующие строки в свой файл manifest.xml.
<activity android:name = ".Youractivity"
android:configChanges = "orientation|screenSize"/>
В разделе активности manifest добавьте:
android:configChanges = "keyboardHidden|orientation"
Добавьте эту строку в манифест:android:configChanges = "orientation|screenSize"
Люди говорят, что вам следует использовать
android:configChanges = "keyboardHidden|orientation"
Но лучший и самый профессиональный способ управлять вращением в Android - использовать класс Loader. Это не известный класс (я не знаю почему), но он намного лучше, чем AsyncTask. Для получения дополнительной информации вы можете прочитать учебные материалы по Android, которые можно найти в курсах Udacity для Android.
Конечно, в качестве другого способа вы можете сохранить значения или представления с помощью onSaveInstanceState и прочитать их с помощью onRestoreInstanceState. Это действительно вам решать.
Да, давайте добавим кучу дополнительного кода, чтобы он выглядел «профессионально». Или как насчет того, чтобы просто придерживаться быстрого, простого, надежного и испытанного способа сделать это с атрибутом configurationChanges.
Вы можете использовать объект ViewModel в своей деятельности.
Объекты ViewModel автоматически сохраняются во время изменения конфигурации, поэтому данные, которые они хранят, немедленно становятся доступными для следующего действия или экземпляра фрагмента. Читать далее:
https://developer.android.com/topic/libraries/architecture/viewmodel
Один из лучших компонентов архитектуры Android, представленный Google, выполнит все ваши требования, а именно ViewModel.
Это предназначено для хранения и управления данными, связанными с пользовательским интерфейсом, в течение жизненного цикла, а также позволяет данным сохраняться при повороте экрана.
class MyViewModel : ViewModel() {
Пожалуйста, обратитесь к этому: https://developer.android.com/topic/libraries/architecture/viewmodel
Есть несколько способов сделать это:
Самостоятельно справляться с изменением ориентации
Другой вариант - самостоятельно справиться с изменением ориентации. Но это не считается хорошей практикой.
Добавьте это в свой файл манифеста.
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 = "портрет"
Или реализуйте это программно в своей деятельности:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
ИЛИ Сохранить состояние активности
Вы можете сохранить состояние активности в 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);
}
а затем используйте пакет для восстановления состояния.
@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
}
}
добавьте этот код в свой menufests.xml.
это ваша деятельность.
<activity
....
..
android:configChanges = "orientation|screenSize"/>
В это сообщение в блоге есть довольно полное объяснение того, как сохранить долго выполняющиеся асинхронные задачи при изменении конфигурации активности!