Intereting Posts
Как определить анимацию размера экрана в формате XML Получить путь к базе данных Андроид expandablelistview не расширяет или не получает события кликов Элемент с приложением: showAsAction не отображается Android Studio: сборка Gradle не выполняется – выполнение выполнено для задачи: compileDebugAidl ' Ненавязчивое всплывающее окно, которое не блокирует перетаскивание n в Android Получение «пакета android.support.multidex не существует» после обновления до Android Studio 2.3 Видимость панели обнаружения / TYPE_SYSTEM_OVERLAY не изменяется автоматически Android: AutoCompleteTextView показывает предложения, когда текст не вводится RecycleView устанавливает неправильную высоту для элементов Поддерживает ли веб-представление на Android поддержку SSL? Можно ли вызвать startActivityForResult из адаптера? Получить контекст внутри onClick (DialogInterface v, int buttonId)? Как отключить автоматическое отображение консолей АБР в Eclipse? Разница между onPause и onStop ()

IllegalStateException при замене фрагмента

Это небольшое тестовое приложение для Android 2.2, использующее пакет совместимости. Это (конечно, конечно) способ, которым я пытаюсь заменить фрагмент при получении щелчка. Я пытаюсь заменить его новым (другим) экземпляром того же класса Fragment. Как я объясню, он работает не так, как ожидалось, и мне нужна помощь:

public class MainFragmentActivity extends FragmentActivity { ... public void myAction(View view) { ... RightFragment newRightFrag = RightFragment.newInstance(myNewOption); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out); ft.replace(R.id.landscape_right_fragment, newRightFrag); ft.commit(); } } 

Вы наверняка увидели, что моя ошибка. В любом случае давайте немного разъясним, что должно делать приложение:

Альбомная ориентация :

 --------- ---------- | L | R | -> click -> | L | R2 | --------- ---------- 

В альбомной ориентации активность имеет вид с двумя фрагментами: « leftLand » и « rightLand », и если вы нажмете кнопку фрагмента « leftLand », то он изменит создание нового фрагмента и заменит экземпляр « RightLand » Fragment другим Экземпляр того же класса FragamentActivity. Что отличает эти два экземпляра, это параметр, передаваемый «newInstance (int)», он основан на нажатой кнопке.

Портрет Ориентация:

 ----- ----- | | | | | L | -> click -> | R | | | | | ----- ----- 

В портретной ориентации он просто показывает фрагмент « leftPort » (имеет тот же макет, что и « leftLand »), и если вы нажмете на его кнопку, тогда он запускает Intent и запускает RightFragmentActivity, который показывает фрагмент « rightLand »,

Он отлично работает … если я не заменю правый фрагмент. Если я это сделаю (нажав кнопку в альбомной ориентации), то при последующем изменении ориентации (перезапуск активности) FragmentActivity не сможет запустить из-за « IllegalStateException: Fragment RightFragment did not create a view », как это:

 D/AndroidRuntime( 1428): Shutting down VM W/dalvikvm( 1428): threadid=1: thread exiting with uncaught exception (group=0x4001d800) E/AndroidRuntime( 1428): FATAL EXCEPTION: main E/AndroidRuntime( 1428): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.agm.test/com.agm.test.MainFragmentActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment E/AndroidRuntime( 1428): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) E/AndroidRuntime( 1428): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) E/AndroidRuntime( 1428): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815) E/AndroidRuntime( 1428): at android.app.ActivityThread.access$2400(ActivityThread.java:125) E/AndroidRuntime( 1428): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037) E/AndroidRuntime( 1428): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime( 1428): at android.os.Looper.loop(Looper.java:123) E/AndroidRuntime( 1428): at android.app.ActivityThread.main(ActivityThread.java:4627) E/AndroidRuntime( 1428): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime( 1428): at java.lang.reflect.Method.invoke(Method.java:521) E/AndroidRuntime( 1428): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) E/AndroidRuntime( 1428): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) E/AndroidRuntime( 1428): at dalvik.system.NativeStart.main(Native Method) E/AndroidRuntime( 1428): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment E/AndroidRuntime( 1428): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582) E/AndroidRuntime( 1428): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618) E/AndroidRuntime( 1428): at android.view.LayoutInflater.inflate(LayoutInflater.java:407) E/AndroidRuntime( 1428): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) E/AndroidRuntime( 1428): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) E/AndroidRuntime( 1428): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198) E/AndroidRuntime( 1428): at android.app.Activity.setContentView(Activity.java:1647) E/AndroidRuntime( 1428): at com.agm.test.MainFragmentActivity.onCreate(MainFragmentActivity.java:25) E/AndroidRuntime( 1428): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) E/AndroidRuntime( 1428): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) E/AndroidRuntime( 1428): ... 12 more E/AndroidRuntime( 1428): Caused by: java.lang.IllegalStateException: Fragment com.agm.test.RightFragment did not create a view. E/AndroidRuntime( 1428): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:287) E/AndroidRuntime( 1428): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558) E/AndroidRuntime( 1428): ... 21 more W/ActivityManager( 59): Force finishing activity com.agm.test/.MainFragmentActivity 

Я понял, что старый « RightFragment » не был уничтожен после замены. Вероятно, это следствие моего неправильного пути, чтобы попытаться заменить его.

Любая помощь могла бы быть полезна.

Заранее спасибо!

/ Ангел Галиндо Муньос

Solutions Collecting From Web of "IllegalStateException при замене фрагмента"

Я думаю, что вы, возможно, неправильно поняли мой комментарий, поэтому я приведу более подробное объяснение здесь.

Одна проблема, которая обычно возникает при удалении или замене фрагментов, заключается в попытке удалить фрагмент, который был добавлен в макет через XML, а не программно в Java. Это не то же самое, что раздувать собственный макет фрагмента в функции onCreateView() кода Java фрагмента (это то, что вы, кажется, описываете в своем ответе на мой комментарий). Чтобы проиллюстрировать то, о чем я говорю, я покажу вам два способа, которыми люди пытаются удалить / заменить фрагменты.

Это неправильный способ сделать это:

XML-макет:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:name="com.example.ExampleFragment" android:id="@+id/example_fragment" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout> 

Ява:

 swapFragment() { Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); transaction.commit(); } 

Этот код не будет выполняться так, как вы ожидаете. Исходный фрагмент, добавленный в макет XML, не будет удален. Это связано с тем, что макеты XML предназначены для описания элементов статического макета. Вы можете изменить их содержимое во время выполнения или скрыть их, но вы не можете удалить эти вещи из макета. Это то, о чем говорила Диана Хакборн в дискуссионной теме, с которой я связался раньше.

Это правильный способ сделать это (по крайней мере, по моему опыту):

XML-макет:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Fragment will go here eventually, but it's not added in the layout --> </LinearLayout> 

Ява:

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_layout); ExampleFragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.add(R.id.fragment_container, newFragment); transaction.commit(); } 

 swapFragment() { Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); transaction.commit(); } 

Эта стратегия не добавляет фрагмент в исходный макет. Вместо этого он добавляет его в код Java при создании Activity. Это позволяет удалить его из макета (используя remove() или replace() )

Это может не решить вашу проблему, но это общая трудность, которую создают Фрагменты. Вы можете убедиться, что вы добавляете Фрагменты соответствующим образом, чтобы их можно было удалить, а затем, если это не решит проблему, мы можем устранить ее.

Есть и другой способ, когда вы разрабатываете приложения для планшетов с большими экранами, вы можете раздувать разницу между различными ориентациями экрана. Вам просто нужно создать два макета и называть их портретом или пейзажем, в onCreate просто надуть xml в соответствии с Ориентация.

В событии onClick просто укажите ориентацию с помощью: getResources (). GetConfiguration ().

И делай свои вещи