android - 每次选择一个选项卡时,onCreate 调用两个选项卡

标签 android actionbarsherlock

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

当我选择任何选项卡时,将按预期调用关联 fragment 的 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 也被调用(不应该发生)

我已经阅读了几个可能的问题并进行了检查以确保它不会在这里发生:

  1. 不为每个标签使用唯一标签(它们是唯一的)
  2. 模拟器有调用 onCreate 两次的错误(我在我的 ICS 设备上得到相同的行为)

所以这不是前面两种可能性,我会完全没有想法。该程序运行良好,但加载两个 fragment (它们是 webview)需要太多时间,这不是我预期的行为。

这是创建选项卡主机的主要 Activity 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)
    {
    }

}
}

这是选项卡 fragment 的代码: 已编辑:

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

最佳答案

标签计数将从 0 开始,所以在 viewPager 中你必须像下面这样设置屏幕限制

例如,如果您有 3 个标签,只需给出

viewPager.setOffscreenPageLimit(2);

关于android - 每次选择一个选项卡时,onCreate 调用两个选项卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9610495/

相关文章:

java.io.ioException : read failed, 套接字可能关闭或超时 Java Android Studio

android - 如何在 Android 上实现 Material Design 展开/折叠列表?

android - MVVM 中 View 之间的通信

android - 具有 3D 模型的基于位置的增强现实框架(Android、iOS)?

android - Action 条 Sherlock 错误

Android 操作栏微调器文本颜色

android - 禁用 Appcompact_v7 包含 : Android

android - 在 2 个 View 之间放置一个 recyclerview

android - 从 fragment 创建操作栏选项卡

android - Sherlock 操作栏 RTL