2

colleagues! I've got an exception which I don't know how to avoid. I created TabHost with ViewPager in SherlockFragmentActivity. TabHost contains fragments.

Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.tabs_fragment_layout);
    mTabHost = (TabHost) findViewById(android.R.id.tabhost);
    mViewPager = (ViewPager) findViewById(R.id.pager);

    mTabHost.setup();
    setupTabs();

    if (savedInstanceState != null) {
        mTabHost.setCurrentTabByTag(savedInstanceState.getString(CURRENT_TAB_KEY));
    }
}

private void setupTabs() {
    nameTabs = getResources().getStringArray(R.array.tabs);

    mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);

    mTabsAdapter.addTab(newTab(TABS_TAG_1, R.drawable.ic_action_countries, 
            nameTabs[COUNTRIES_TAB_INDEX]), CountryTabFragment.class, null);
    mTabsAdapter.addTab(newTab(TABS_TAG_2, R.drawable.ic_action_settings_dark, 
            nameTabs[SETTINGS_TAB_INDEX]),UltiPreferenceFragment.class, null);
    mTabsAdapter.addTab(newTab(TABS_TAG_3, R.drawable.ic_action_about, 
            nameTabs[ABOUT_TAB_INDEX]), AboutFragment.class, null);
}

private TabSpec newTab (String tag, int iconId, String tabTitle) {
    TabSpec tab = mTabHost.newTabSpec(tag);
    tab.setIndicator(tabTitle, getResources().getDrawable(iconId));
    return tab;
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(CURRENT_TAB_KEY, mTabHost.getCurrentTabTag());
}

 private Fragment getFragmentByIndex(ViewPager container, int position) {
     String name = makeFragmentName(container.getId(), position);
     return  getSupportFragmentManager().findFragmentByTag(name);
 }

 private String makeFragmentName(int viewId, int index) {
     return getString(R.string.fragment_name_pattern, viewId, index);
 }

public static class TabsAdapter extends FragmentPagerAdapter 
        implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {

     private final Context mContext;
     private final TabHost mTabHost;
     private final ViewPager mViewPager;
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();

     static final class TabInfo {
         private final String tag;
         private final Class<?> clss;
         private final Bundle args;

         TabInfo(String tag, Class<?> clss, Bundle args) {
             this.tag = tag;
             this.clss = clss;
             this.args = args;
         }
     }

     static class DummyTabFactory implements TabHost.TabContentFactory {
         private final Context mContext;

         public DummyTabFactory(Context context) {
             mContext = context;
         }

         @Override
         public View createTabContent(String tag) {
             View view = new View(mContext);
             view.setMinimumWidth(0);
             view.setMinimumHeight(0);
             return view;
         }
     }

     public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
         super(activity.getSupportFragmentManager());
         mContext = activity;
         mTabHost = tabHost;
         mViewPager = pager;
         mTabHost.setOnTabChangedListener(this);
         mViewPager.setAdapter(this);
         mViewPager.setOnPageChangeListener(this);
         mViewPager.setId(R.id.view_pager);
     }

     public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
         tabSpec.setContent(new DummyTabFactory(mContext));
         String tag = tabSpec.getTag();

         TabInfo info = new TabInfo(tag, clss, args);
         mTabs.add(info);
         mTabHost.addTab(tabSpec);
         notifyDataSetChanged();
     }

     @Override
     public int getCount() {
         return mTabs.size();
     }

     @Override
     public Fragment getItem(int position) {
         TabInfo info = mTabs.get(position);
         return Fragment.instantiate(mContext, info.clss.getName(), info.args);
     }

     @Override
    public int getItemPosition(Object object) {
        return PagerAdapter.POSITION_NONE;
    }

    @Override
     public void onTabChanged(String tabId) {
         int position = mTabHost.getCurrentTab();
         mViewPager.setCurrentItem(position);
     }

     @Override
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
     }

     @Override
     public void onPageSelected(int position) {
         TabWidget widget = mTabHost.getTabWidget();
         int oldFocusability = widget.getDescendantFocusability();
         widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
         mTabHost.setCurrentTab(position);
         widget.setDescendantFocusability(oldFocusability);
     }

     @Override
     public void onPageScrollStateChanged(int state) {
     }
}

On 7'' device I have 2 layouts for FirstFragment of TabHost, one for portrait and for landscape. When I rotate the screen it have to be changed layout. Unfortunately I can`t recreate activity becouse in such case I lose context for dialogues (DialogFragment) and other long-term processes , which available in app while rotating the screen. So, 1) I use in AndroidManifest.xml

android:configChanges="orientation|screenSize"

2) override onConfigurationChanged()-method in Activity:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    int oldConfigOrientation = getRequestedOrientation();
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation != oldConfigOrientation) {
        Toast.makeText(this, "orientation changed!", Toast.LENGTH_SHORT).show();
        mTabsAdapter.notifyDataSetChanged();
    }
}

3) and ovveride getItemPosition()-method in FragmentPagerAdapter for recreation layout of tab. Trouble occures when I rotate screen and it should be loaded one-panel layout with one fragment instead two-panel layout:

04-12 12:30:44.019: E/AndroidRuntime(11151): java.lang.IllegalArgumentException: No view found for id 0x7f05004f (com.ziko.widget:id/setup_layout_fragment) for fragment SetupCityFragment{410fac80 #1 id=0x7f05004f}
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:903)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1861)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1474)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1264)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:672)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:461)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.view.ViewPager.populate(ViewPager.java:1011)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:522)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:494)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:874)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2688)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:35)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at com.ziko.widget.ui.ConfigurationActivity.onConfigurationChanged(ConfigurationActivity.java:140)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.app.ActivityThread.performConfigurationChanged(ActivityThread.java:3461)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.app.ActivityThread.handleConfigurationChanged(ActivityThread.java:3585)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1220)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.os.Looper.loop(Looper.java:137)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at android.app.ActivityThread.main(ActivityThread.java:4424)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at java.lang.reflect.Method.invokeNative(Native Method)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at java.lang.reflect.Method.invoke(Method.java:511)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
04-12 12:30:44.019: E/AndroidRuntime(11151):    at dalvik.system.NativeStart.main(Native Method)

This trouble have never occured when I rotate screen from one-panel (portrait) layout to two-panel (landscape), but always when opposite. Exception throws while invoking method mTabsAdapter.notifyDataSetChanged(); in onConfigurationChanged().

Can anyone explain the reason of exception and how to avoid it in future? Maybe there is the other way how to provide changing tab`s layout while rotation the screen?

Alex Zezekalo
  • 1,031
  • 2
  • 17
  • 34

0 Answers0