Note that there are some explanatory texts on larger screens.

plurals
  1. POInflate Exception when Switching Between Orientations and Having Dynamic Non UI Fragments and Separate Layout Files
    text
    copied!<p>I have been looking at this and trying to figure the problem out for a day now, but with no luck. I usually ask questions as a final measure, so I am kind of desperate right now as nothing that was recommended in other questions worked for me... And I've been trying hundreds of solutions. It could be that I am just having problems figuring out the correct way of asking it.</p> <p>Here is what I have in my project:</p> <p><strong>A base fragment activity class that all activities in my project extend:</strong></p> <pre><code>public abstract class BaseFragmentActivity extends SherlockFragmentActivity implements IActivity { protected CacheFragment cacheFragment; /* * (non-Javadoc) * * @see * com.actionbarsherlock.app.SherlockActivity#onOptionsItemSelected(com. * actionbarsherlock.view.MenuItem) */ @Override public boolean onOptionsItemSelected(final MenuItem item) { NavigationHandler.switchToActivity(this, item.getItemId()); return true; } /* * (non-Javadoc) * * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.getSupportActionBar().setHomeButtonEnabled(this.isHomeButtonEnabled()); this.getSupportActionBar().setDisplayHomeAsUpEnabled(this.isHomeDisplayedAsUp()); } /** * Returns whether the home button is enabled. * * @return &lt;code&gt;TRUE&lt;/code&gt; if the home button is enabled. */ public abstract boolean isHomeButtonEnabled(); /** * Returns whether the home button should be displayed as an up button with * a arrow on the left. * * @return &lt;code&gt;TRUE&lt;/code&gt; if the home button should be shown with an * arrow. */ public abstract boolean isHomeDisplayedAsUp(); /** * Gets the cache manager of the given fragment activity. */ public CacheManager getCacheManager() { if (this.cacheFragment == null) { this.cacheFragment = CacheFragment.getOrCreateCacheFragment(this.getSupportFragmentManager(), this); } return this.cacheFragment.getCacheManager(); } /* * (non-Javadoc) * * @see com.actionbarsherlock.app.SherlockFragmentActivity#onPause() */ @Override protected void onPause() { super.onPause(); if (this.cacheFragment != null) { this.cacheFragment.getCacheManager().flushDiskCache(); } } } </code></pre> <p><strong>A home activity with two different layouts for portrait (in layout-port) and landscape, which extends the base activity class:</strong></p> <p>Portrait:</p> <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".HomeActivity" &gt; &lt;fragment android:id="@+id/teaserFragment" android:layout_width="match_parent" android:layout_height="wrap_content" class="com.nikolov.ivan.android.metalafisha.fragments.TeaserListFragment" &gt; &lt;/fragment&gt; &lt;/RelativeLayout&gt; </code></pre> <p>Landscape:</p> <pre><code>&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="true" android:orientation="horizontal" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".HomeActivity" &gt; &lt;fragment android:id="@+id/teaserFragment" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="2" class="com.nikolov.ivan.android.metalafisha.fragments.TeaserListFragment" &gt; &lt;/fragment&gt; &lt;fragment android:id="@+id/articleFragment" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/article_detail_landscape_margin_left" android:layout_weight="3" class="com.nikolov.ivan.android.metalafisha.fragments.ArticleFragment" &gt; &lt;/fragment&gt; &lt;/LinearLayout&gt; </code></pre> <p><strong>Teaser fragment:</strong></p> <p>Layout:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lvItems" android:layout_width="match_parent" android:layout_height="wrap_content" android:choiceMode="singleChoice" &gt; &lt;/ListView&gt; </code></pre> <p><strong>Article fragment</strong>:</p> <p>Layout:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/scrollArticle" android:layout_width="fill_parent" android:layout_height="wrap_content" &gt; &lt;LinearLayout android:id="@+id/layoutLinear" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" &gt; &lt;/LinearLayout&gt; &lt;/ScrollView&gt; </code></pre> <p><strong>A cache fragment:</strong></p> <pre><code>public class CacheFragment extends SherlockFragment { private static final String TAG = "CacheFragment"; private CacheManager cacheManager; public CacheFragment() { } /** * Gets the application cache fragment or creates a new one. */ public static CacheFragment getOrCreateCacheFragment(final FragmentManager fm, final Context context) { CacheFragment result = (CacheFragment) fm.findFragmentByTag(CacheFragment.TAG); if (result == null) { result = new CacheFragment(); result.cacheManager = new CacheManager(context); FragmentTransaction ft = fm.beginTransaction(); ft.add(result, CacheFragment.TAG); ft.commit(); } return result; } public CacheManager getCacheManager() { return this.cacheManager; } /* * (non-Javadoc) * * @see * android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, * android.view.ViewGroup, android.os.Bundle) */ @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { return null; } /* * (non-Javadoc) * * @see android.support.v4.app.Fragment#onCreate(android.os.Bundle) */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setRetainInstance(true); } } </code></pre> <p>The idea of the cache fragment is to have no UI and to be used and retained during configuration changes. All disk accesses are done on a thread different than the main one.</p> <p>Here are two scenarios now:</p> <ol> <li>Start the application in landscape mode - everything is fine, things are visualized normally and there are no problems at all when I change the orientation or do whatever with the app.</li> <li>Start the application in portrait mode - the problems come here... When I switch the orientation I am expecting to get the master-detail layout. The activity gets recreated and should use the landscape layout, the <strong>CacheFragment</strong> should be there, since it was created to retain its instance and this seems to be the case. I see the call to the <strong>onCreateView</strong> of the first layout fragment (<strong>TeaserListFragment</strong>) and then I get the following exception:</li> </ol> <p>LogCat:</p> <pre><code>09-08 15:41:37.104: E/AndroidRuntime(1731): FATAL EXCEPTION: main 09-08 15:41:37.104: E/AndroidRuntime(1731): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nikolov.ivan.android.metalafisha/com.nikolov.ivan.android.metalafisha.HomeActivity}: android.view.InflateException: Binary XML file line #21: Error inflating class fragment 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.ActivityThread.access$2400(ActivityThread.java:125) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.os.Handler.dispatchMessage(Handler.java:99) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.os.Looper.loop(Looper.java:123) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.ActivityThread.main(ActivityThread.java:4627) 09-08 15:41:37.104: E/AndroidRuntime(1731): at java.lang.reflect.Method.invokeNative(Native Method) 09-08 15:41:37.104: E/AndroidRuntime(1731): at java.lang.reflect.Method.invoke(Method.java:521) 09-08 15:41:37.104: E/AndroidRuntime(1731): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 09-08 15:41:37.104: E/AndroidRuntime(1731): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 09-08 15:41:37.104: E/AndroidRuntime(1731): at dalvik.system.NativeStart.main(Native Method) 09-08 15:41:37.104: E/AndroidRuntime(1731): Caused by: android.view.InflateException: Binary XML file line #21: Error inflating class fragment 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.view.LayoutInflater.rInflate(LayoutInflater.java:618) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.view.LayoutInflater.inflate(LayoutInflater.java:407) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.view.LayoutInflater.inflate(LayoutInflater.java:320) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.view.LayoutInflater.inflate(LayoutInflater.java:276) 09-08 15:41:37.104: E/AndroidRuntime(1731): at com.actionbarsherlock.internal.ActionBarSherlockCompat.setContentView(ActionBarSherlockCompat.java:840) 09-08 15:41:37.104: E/AndroidRuntime(1731): at com.actionbarsherlock.app.SherlockFragmentActivity.setContentView(SherlockFragmentActivity.java:262) 09-08 15:41:37.104: E/AndroidRuntime(1731): at com.nikolov.ivan.android.metalafisha.HomeActivity.onCreate(HomeActivity.java:27) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 09-08 15:41:37.104: E/AndroidRuntime(1731): ... 12 more 09-08 15:41:37.104: E/AndroidRuntime(1731): Caused by: java.lang.IllegalStateException: Fragment com.nikolov.ivan.android.metalafisha.fragments.ArticleFragment did not create a view. 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:293) 09-08 15:41:37.104: E/AndroidRuntime(1731): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558) 09-08 15:41:37.104: E/AndroidRuntime(1731): ... 21 more </code></pre> <p>Seems like something strange is going on when I have the <strong>CacheFragment</strong> created before switching to landscape mode.</p> <p>Another thing I notice is that I see calls to the <strong>onCreateView</strong>, when the Android documentation states that it should not be called for no UI fragments.</p> <p>I made sure that I have IDs in the layout file, I even checked if they are globally unique for the application and many other things that seemed reasonable, but I still see the same result. The only way this doesn't happen is if I don't add the <strong>CacheFragment</strong> with the transaction, but then there is really no point of having it...</p> <p>Based on the message it looks like Android is confusing the <strong>CacheFragment</strong> with the <strong>ArticleFragment</strong>...</p> <p>Any help will be greatly appreciated, as I seem to run out of ideas what I can be doing wrong!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload