OnCreate calls two tabs each time one tab is selected

I have a tabbed application built with snippets and an ActionBarSherlock. I have 7 tabs. This is what happens.

When I select any tab, the onCreate method for the associated fragment is called as expected. The problem is that the onCreate method is called for the next neighboring tab. For instance:

  • The application starts in tab1 and onCreate is called as expected
  • tab2 onCreate is also called (should not be)
  • -------
  • Click on tab2 and onCreate is called as expected (although it has already been called)
  • tab3 onCreate is also called (should not be)
  • -------
  • Click on tab6 and onCreate is called as expected
  • tab7 onCreate is also called (should not be)
  • -------
  • And really strange, click on tab7 (last tab)
  • tab6 (from 2nd to last tab) onCreate is also called (should not be)

I read a couple of possible problems and checked to make sure this is not happening here:

  • Do not use a unique tag for each tab (they are unique)
  • The emulator has an error that calls onCreate twice (I get the same behavior on my ICS device)

Thus, these are not two previous opportunities, and I will not fully understand ideas. The program works fine, but loading two fragments (which are webviews) takes too much time and does not match the expected behavior.

Here is my code for the main onCreate action, which creates the tab host: By:

public class SynergyWorldwideActivity extends SherlockFragmentActivity { //TabHost mTabHost; ViewPager mViewPager; TabsAdapter mTabsAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Set up the view pager setContentView(R.layout.fragment_tabs_pager); mViewPager = (ViewPager)findViewById(R.id.pager); // Set up action bar final ActionBar bar = getSupportActionBar(); bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); bar.setDisplayShowTitleEnabled(true); //bar.setDisplayShowHomeEnabled(false); // Creat tabs with bundled URLs Bundle tab1Args=new Bundle(), tab2Args=new Bundle(), tab3Args=new Bundle(), tab4Args=new Bundle(), tab5Args=new Bundle(), tab6Args=new Bundle(), tab7Args=new Bundle(); tab1Args.putString("tabURL", getString(R.string.webtab1_URL)); tab2Args.putString("tabURL", getString(R.string.webtab2_URL)); tab3Args.putString("tabURL", getString(R.string.webtab3_URL)); tab4Args.putString("tabURL", getString(R.string.webtab4_URL)); tab5Args.putString("tabURL", getString(R.string.webtab5_URL)); tab6Args.putString("tabURL", getString(R.string.webtab6_URL)); tab7Args.putString("tabURL", getString(R.string.webtab7_URL)); mTabsAdapter = new TabsAdapter(this, mViewPager); mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab1_name)), WebTabFragment.MyWebviewFragment.class, tab1Args); mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab2_name)), WebTabFragment.MyWebviewFragment.class, tab2Args); mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab3_name)), WebTabFragment.MyWebviewFragment.class, tab3Args); mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab4_name)), WebTabFragment.MyWebviewFragment.class, tab4Args); mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab5_name)), WebTabFragment.MyWebviewFragment.class, tab5Args); mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab6_name)), WebTabFragment.MyWebviewFragment.class, tab6Args); mTabsAdapter.addTab(bar.newTab().setText(getString(R.string.webtab7_name)), WebTabFragment.MyWebviewFragment.class, tab7Args); if (savedInstanceState != null) { bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("tab", getActionBar().getSelectedNavigationIndex()); } /** * This is a helper class that implements the management of tabs and all * details of connecting a ViewPager with associated TabHost. It relies on a * trick. Normally a tab host has a simple API for supplying a View or * Intent that each tab will show. This is not sufficient for switching * between pages. So instead we make the content part of the tab host * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy * view to show as the tab content. It listens to changes in tabs, and takes * care of switch to the correct paged in the ViewPager whenever the selected * tab changes. */ public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener{ private final Context mContext; //private final TabHost mTabHost; private final ActionBar mActionBar; private final ViewPager mViewPager; private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); static final class TabInfo { private final Class<?> clss; private final Bundle args; TabInfo(Class<?> _class, Bundle _args) { clss = _class; args = _args; } } public TabsAdapter(FragmentActivity activity, ViewPager pager) { super(activity.getSupportFragmentManager()); mContext = activity; mActionBar = ((SherlockFragmentActivity) activity).getSupportActionBar(); mViewPager = pager; mViewPager.setAdapter(this); mViewPager.setOnPageChangeListener(this); } public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { TabInfo info = new TabInfo(clss, args); tab.setTag(info); tab.setTabListener(this); mTabs.add(info); mActionBar.addTab(tab); notifyDataSetChanged(); } @Override public int getCount() { int iCount = mTabs.size(); return iCount; } @Override public Fragment getItem(int position) { TabInfo info = mTabs.get(position); return Fragment.instantiate(mContext, info.clss.getName(), info.args); } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { mActionBar.setSelectedNavigationItem(position); } @Override public void onPageScrollStateChanged(int state) { } @Override public void onTabSelected(Tab tab) { Object tag = tab.getTag(); for (int i=0; i<mTabs.size(); i++) { if (mTabs.get(i) == tag) { mViewPager.setCurrentItem(i); } } } @Override public void onTabUnselected(Tab tab) { } @Override public void onTabReselected(Tab tab) { } } } 

Here is the code for the tab fragments: Editorial:

 public class WebTabFragment extends SherlockFragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(savedInstanceState == null) { FragmentManager fm = getSupportFragmentManager(); if (fm.findFragmentById(android.R.id.content) == null) { MyWebviewFragment myWebView = new MyWebviewFragment(); fm.beginTransaction().add(android.R.id.content, myWebView).commit(); } } } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //outState.putString("tabNumber", mTabNumber); } public static class MyWebviewFragment extends SherlockFragment { final static private String tag = MyWebviewFragment.class.getSimpleName(); String mTabURL; private WebView mWebView = null; static final int REFRESH_ID = Menu.FIRST; private ProgressDialog spinnerDlg; @Override public void onSaveInstanceState(Bundle outState) { if(mWebView.saveState(outState) == null) Log.i(tag,"Saving state FAILED!"); else Log.i(tag, "Saving state succeeded."); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); setHasOptionsMenu(true); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { menu.add(Menu.NONE, REFRESH_ID, 0, getString(R.string.refresh_string)) .setIcon(R.drawable.ic_action_refresh) .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case REFRESH_ID: if(mWebView != null) mWebView.reload(); return true; default: return super.onOptionsItemSelected(item); } } /** * When creating, retrieve this instance number from its arguments. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Tell the framework to try to keep this fragment around // during a configuration change. setRetainInstance(true); mTabURL = getArguments() != null ? getArguments().getString("tabURL") : "http://www.google.com"; } /** * The Fragment UI is just a simple text view showing its * instance number. */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Create view object to return View v = inflater.inflate(R.layout.webview_layout, container, false); // Set up webview object if (mWebView != null) { mWebView.destroy(); } mWebView = (WebView)v.findViewById(R.id.webview_fragment); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.setOnKeyListener(new OnKeyListener(){ @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { mWebView.goBack(); return true; } return false; } }); // Check to see if it has been saved and restore it if true if(savedInstanceState != null) { if (savedInstanceState.isEmpty()) Log.i(tag, "Can't restore state because bundle is empty."); else { if (mWebView.restoreState(savedInstanceState) == null) Log.i(tag, "Restoring state FAILED!"); else Log.i(tag, "Restoring state succeeded."); } } else { // Load web page mWebView.setWebViewClient(new MyWebViewClient()); mWebView.getSettings().setPluginsEnabled(true); mWebView.getSettings().setBuiltInZoomControls(false); mWebView.getSettings().setSupportZoom(false); mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); mWebView.getSettings().setAllowFileAccess(true); mWebView.getSettings().setDomStorageEnabled(true); mWebView.loadUrl(mTabURL); } return v; } @Override public void onDestroy() { super.onDestroy(); } @Override public void onDestroyView() { super.onDestroyView(); } @Override public void onPause() { super.onPause(); } @Override public void onResume() { super.onResume(); } @Override public void onConfigurationChanged(Configuration newConfig) { // TODO Auto-generated method stub super.onConfigurationChanged(newConfig); } public class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // YouTube video link if (url.startsWith("http://youtu.be")) { String urlSubString = url.substring("http://youtu.be/".length()); String newURL = String.format("http://www.youtube.com/v/%s", urlSubString); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(newURL))); return (true); } return (false); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); if(spinnerDlg == null) { spinnerDlg = new ProgressDialog(getActivity()); spinnerDlg.setMessage("Loading...."); spinnerDlg.show(); } } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if(spinnerDlg != null) { spinnerDlg.dismiss(); } spinnerDlg = null; } } } } 
+3
source share
4 answers

The number of tabs will start from form 0, so in the viewPager you must set the screen limit as shown below

Example if you have 3 tabs just give

viewPager.setOffscreenPageLimit (2);

+3
source

This is one of the properties of tabs. It loads the second, so you do not go to the zero tab. You can override the tab class and handle it yourself if you want: D.

+2
source

If you use fragments, consider using ViewPager. Its much easier to implement and faster in response.

example here, http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html

0
source

You speak

onCreate is also called (should not be)

But this is exactly what should happen if you use ViewPager. How else could you see the fragment if you draw it halfway between the first and second tabs?

If you click on tab 2, it will be recreated, maybe because it is destroyed. Try overriding getItemPosition as follows:

  @Override public int getItemPosition(Object object) { return POSITION_NONE; } 
0
source

Source: https://habr.com/ru/post/919203/


All Articles