Intereting Posts
Android – ImageView On Click Выполнение горизонтальной / вертикальной прокрутки пальцев в сотовом андроидном веб-виде / webkit? Есть ли кто-нибудь знает, как getWindow () в службе на Android? Не показывать Android и AVD-менеджер в eclipse Как получить предпочтительные юниты пользователя? (Метрические (метры) или имперские (мили))? Получить контекст приложения во фрагменте в Android? Проблема с глубоким связыванием Android! Как использовать схему пользовательского URL-адреса myapp: // some_data Android Studio: Исключить файл ресурсов в ресурсах sourceSets Поиск «PaintCode» для Android Как захватить пользовательский размер изображения с помощью камеры в Android? Метод SQLiteDatabase.query TaskStackBuilder и дополнительные функции для заднего стека Как использовать ActionBarActivity с Theme.Material Есть ли какой-то генератор «Feature Graphic» для Google Play? Использование Glide для Android, как мне загружать изображения из активов и ресурсов

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 ().

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