onCreate每次选择一个选项卡时都会调用两个选项卡

时间:2012-03-07 23:03:01

标签: android actionbarsherlock

我有一个使用片段和ActionBarSherlock构建的选项卡式应用程序。我有7个标签。这就是发生的事情。

当我选择任何选项卡时,将按预期调用相关片段的onCreate方法。问题是也为下一个相邻的选项卡调用onCreate方法。例如:

  1. 应用程序在tab1中启动,onCreate按预期调用
  2. tab2 onCreate也被调用(不应该发生)
  3. -------
  4. 点击tab2并按预期调用onCreate(即使它已被调用)
  5. tab3 onCreate也被调用(不应该发生)
  6. -------
  7. 点击tab6,onCreate按预期调用
  8. tab7 onCreate也被调用(不应该发生)
  9. -------
  10. 非常奇怪,点击tab7(最后一个标签)
  11. tab6(倒数第二个标签)onCreate也被调用(不应该发生)
  12. 我已经阅读了几个可能的问题并检查以确保它不会发生在这里:

    1. 不为每个标签使用唯一标记(它们是唯一的)
    2. 模拟器有两次调用onCreate的错误(我的ICS设备上的行为相同)
    3. 所以这不是以前的两种可能性,而且我完全没有想法。该程序运行正常,但加载两个片段(这是Webview)需要花费太多时间,而不是我期望的行为。

      这是我创建标签主机的主要活动onCreate的代码: 的编辑:

      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)
          {
          }
      
      }
      }
      

      以下是标签片段的代码: 的编辑:

      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's 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's 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;
             }
          }
      }
      }
      

4 个答案:

答案 0 :(得分:3)

标签计数将从0开始,因此在viewPager中您必须设置屏幕限制,如下所示

示例如果您有3个标签,只需提供

viewPager.setOffscreenPageLimit(2);

答案 1 :(得分:2)

这是标签的一个属性。它会加载第二个,因此您不会滑动到空制表符。如果需要,欢迎您覆盖制表符并自行处理:D。

答案 2 :(得分:0)

如果您使用的是片段,请考虑使用ViewPager。它更容易实现,响应更快。

这里的例子, http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html

答案 3 :(得分:0)

你说

  

onCreate也被调用(不应该发生)

但是,如果您使用ViewPager,那将会发生什么。如果你在第一个和第二个标签之间滑动它,你怎么看到片段?

如果点击标签2,它可能会重新创建,因为它已被销毁。尝试覆盖getItemPosition,如下所示:

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