使用不同的方向将片段分配给ActionBar中的选项卡

我有3个片段和一个活动。 我想在ActionBar上启用选项卡,并为每个选项卡分配一个Fragment 。 我如何正确地把它钩住?

原来的post

我有一个使用Google I / O应用程序开发的应用程序。 我已经在ActionBar实现了选项卡。 他们似乎正在工作,直到平板电脑的方向改变。 例如,所有3个选项卡都有一个Fragment 。 我可以在它们之间切换,但是当我改变方向时,无论我上一次查看的Fragment是否可见,但是单击这些标签不再改变视图…就像它们已经断开连接一样。 正如所料,回到原来的方向不“解决”它。

我已经考虑过保存和恢复状态,但是我没有看到这些将如何帮助。

编辑

模块级别:

 Fragment mFragmentA = (Fragment) new AFragmentTab(); Fragment mFragmentB = (Fragment) new BFragmentTab(); Fragment mFragmentC = (Fragment) new CFragmentTab(); 

我在活动的onCreate有这样的事情:

 ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(false); ActionBar.Tab tabA = actionBar.newTab().setText("text a"); ActionBar.Tab tabB = actionBar.newTab().setText("text b"); ActionBar.Tab tabC = actionBar.newTab().setText("text c"); tabA.setTabListener(this); tabB.setTabListener(this); tabC.setTabListener(this); actionBar.addTab(tabA); actionBar.addTab(tabB); actionBar.addTab(tabC); 

和一个像这样的TabListener

编辑这个被删除

 class MyTabListener implements ActionBar.TabListener { private Fragment mFragment; // Called to create an instance of the listener when adding a new tab public MyTabListener(Fragment fragment) { mFragment = fragment; } public void onTabSelected(Tab tab, FragmentTransaction ft) { ft.add(R.id.fragment_content, mFragment, null); } public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(mFragment); } public void onTabReselected(Tab tab, FragmentTransaction ft) { // do nothing } } 

编辑

我已经移动了TabListener 。 它不是一个单独的类, TabListenerActivity上实现TabListener 。 然后在SelectedUnselected Selected方法,我有这样的:

 public void onTabSelected(Tab tab, FragmentTransaction ft) { switch (tab.getPosition()) { case 0: ft.add(R.id.fragment_content, mFragmentA, null); break; case 1: ft.add(R.id.fragment_content, mFragmentB, null); break; case 2: ft.add(R.id.fragment_content, mFragmentC, null); break; } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { switch (tab.getPosition()) { case 0: ft.remove(mFragmentA); break; case 1: ft.remove(mFragmentB); break; case 2: ft.remove(mFragmentC); break; } } 

它仍然在做同样的事情。 我真的不知道发生了什么。

Solutions Collecting From Web of "使用不同的方向将片段分配给ActionBar中的选项卡"

它看起来像我的答案可以在这里find: http : //developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.html

 /* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.apis.app; import com.example.android.apis.R; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; import android.os.Bundle; import android.widget.Toast; /** * This demonstrates the use of action bar tabs and how they interact * with other action bar features. */ public class FragmentTabs extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final ActionBar bar = getActionBar(); bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); bar.addTab(bar.newTab() .setText("Simple") .setTabListener(new TabListener<FragmentStack.CountingFragment>( this, "simple", FragmentStack.CountingFragment.class))); bar.addTab(bar.newTab() .setText("Contacts") .setTabListener(new TabListener<LoaderCursor.CursorLoaderListFragment>( this, "contacts", LoaderCursor.CursorLoaderListFragment.class))); bar.addTab(bar.newTab() .setText("Apps") .setTabListener(new TabListener<LoaderCustom.AppListFragment>( this, "apps", LoaderCustom.AppListFragment.class))); bar.addTab(bar.newTab() .setText("Throttle") .setTabListener(new TabListener<LoaderThrottle.ThrottledLoaderListFragment>( this, "throttle", LoaderThrottle.ThrottledLoaderListFragment.class))); if (savedInstanceState != null) { bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("tab", getActionBar().getSelectedNavigationIndex()); } public static class TabListener<T extends Fragment> implements ActionBar.TabListener { private final Activity mActivity; private final String mTag; private final Class<T> mClass; private final Bundle mArgs; private Fragment mFragment; public TabListener(Activity activity, String tag, Class<T> clz) { this(activity, tag, clz, null); } public TabListener(Activity activity, String tag, Class<T> clz, Bundle args) { mActivity = activity; mTag = tag; mClass = clz; mArgs = args; // Check to see if we already have a fragment for this tab, probably // from a previously saved state. If so, deactivate it, because our // initial state is that a tab isn't shown. mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction(); ft.hide(mFragment); ft.commit(); } } public void onTabSelected(Tab tab, FragmentTransaction ft) { if (mFragment == null) { mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs); ft.add(android.R.id.content, mFragment, mTag); } else { ft.show(mFragment); } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (mFragment != null) { ft.hide(mFragment); } } public void onTabReselected(Tab tab, FragmentTransaction ft) { Toast.makeText(mActivity, "Reselected!", Toast.LENGTH_SHORT).show(); } } } 

@metallicraft提供的链接已经死了,所以对于那些仍然在这篇文章中遇到困难的人来说,这是一些帮助。 去这里寻求实现标签的帮助。

要查看/阅读原始示例,您可以转到以下文件夹,如果您已经安装了android开发环境: android-sdk\samples\android-14\ApiDemos\src\com\example\android\apis\app\FragmentTabs.java

另外,如果您在方向更改后重叠片段时遇到问题,则与传递的savedinstancestate正确相关。 这里是一个从谷歌教程复制粘贴,解释片段重叠的问题,以及如何避免它:

 import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.news_articles); // Check that the activity is using the layout version with // the fragment_container FrameLayout if (findViewById(R.id.fragment_container) != null) { // However, if we're being restored from a previous state, // then we don't need to do anything and should return or else // we could end up with overlapping fragments. if (savedInstanceState != null) { return; } // Create an instance of ExampleFragment HeadlinesFragment firstFragment = new HeadlinesFragment(); // In case this activity was started with special instructions from an Intent, // pass the Intent's extras to the fragment as arguments firstFragment.setArguments(getIntent().getExtras()); // Add the fragment to the 'fragment_container' FrameLayout getSupportFragmentManager().beginTransaction() .add(R.id.fragment_container, firstFragment).commit(); } } } 

创build一个新的Android示例项目,selectSupport4Demos示例。 你会在那里findFragmentTabs的例子。

我或多或less有同样的问题,但上面提出的解决scheme似乎没有解决我的情况。 最终我find了以下解决scheme:

  @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { if (mFragment == null) { mFragment = Fragment.instantiate(mActivity, mClass.getName()); ft.replace(android.R.id.content, mFragment, mTag); // Use replace iso add } else { ft.attach(mFragment); } } 

这对我很好! 我有这个问题,每当我改变标签的活动重叠:

  mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag); if (mFragment != null && !mFragment.isDetached()) { FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction(); ft.detach(mFragment); ft.commit(); 

再次感谢!

  @Override public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) { // Check if the fragment is already initialized if (mFragment == null) { // If not, instantiate and add it to the activity // Toast.makeText(getApplicationContext(),"TAb "+tab.getPosition(),Toast.LENGTH_LONG).show(); if(tab.getPosition() == 1) { mFragment = new HolderFragment(); fragmentTransaction.add(android.R.id.content, mFragment, mTag); } else if(tab.getPosition() == 0) { mFragment = new FragmentKnowledge(); fragmentTransaction.add(android.R.id.c`enter code here`ontent, mFragment, mTag); } /*else { mFragment = Fragment.instantiate(mActivity, mClass.getName()); fragmentTransaction.add(android.R.id.content, mFragment, mTag); } */ } else { // If it exists, simply attach it in order to show it fragmentTransaction.attach(mFragment); } }