我有一个使用片段和ActionBarSherlock构建的选项卡式应用程序。我有7个标签。这就是发生的事情。
当我选择任何选项卡时,将按预期调用相关片段的onCreate方法。问题是也为下一个相邻的选项卡调用onCreate方法。例如:
我已经阅读了几个可能的问题并检查以确保它不会发生在这里:
所以这不是以前的两种可能性,而且我完全没有想法。该程序运行正常,但加载两个片段(这是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;
}
}
}
}
答案 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;
}