ActionBarSherlock、ViewPager、TabsAdapter 嵌套选项卡片段
Posted
技术标签:
【中文标题】ActionBarSherlock、ViewPager、TabsAdapter 嵌套选项卡片段【英文标题】:ActionBarSherlock, ViewPager, TabsAdapter nested Tab Fragments 【发布时间】:2013-01-01 14:59:27 【问题描述】:我实现了一个带有 ViewPager 和 TabsAdapter 的 ActionBarSherlock。它运行良好,但现在我尝试从加载到“Tab 1”中的框架中“推送”另一个片段。
行为应该是这样的:
我的应用程序中有 3 个选项卡,启动时我看到第一个选项卡,其中有一个带有按钮的片段 按第一个选项卡上的按钮,应替换第一个选项卡上的片段并显示另一个片段我尝试实现此功能,但替换时出现黑色 Fragment。
代码:
FragmentDemoActivity.java
public class FragmentDemoActivity extends SherlockFragmentActivity
CustomViewPager mViewPager;
TabsAdapter mTabsAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mViewPager = (CustomViewPager)findViewById(R.id.pager);
mViewPager.setSwipingEnabled(false);
mTabsAdapter = new TabsAdapter(this, bar, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("tab1"),
FragmentA.class, null);
mTabsAdapter.addTab(bar.newTab().setText("tab2"),
FragmentB.class, null);
setTitle(R.string.app_name);
if (savedInstanceState != null)
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab"));
@Override
protected void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
public static class TabsAdapter extends FragmentPagerAdapter
implements ViewPager.OnPageChangeListener, ActionBar.TabListener
private final Context mContext;
private final ActionBar mBar;
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, ActionBar bar, ViewPager pager)
super(activity.getSupportFragmentManager());
mContext = activity;
mBar = bar;
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
public void addTab(ActionBar.Tab tab, Class<? extends Fragment> clss, Bundle args)
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mBar.addTab(tab);
notifyDataSetChanged();
@Override
public int getCount()
return mTabs.size();
@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)
mBar.setSelectedNavigationItem(position);
@Override
public void onPageScrollStateChanged(int state)
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++)
if (mTabs.get(i) == tag)
mViewPager.setCurrentItem(i,false);
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft)
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft)
FragmentA.java
public class FragmentA extends Fragment
Button button;
int num;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
return inflater.inflate(R.layout.frag_a, group, false);
@Override
public void onActivityCreated (Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
num = 0;
button = (Button) getActivity().findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
FragmentB f1 = new FragmentB();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.pager, f1,"newTag");
ft.show(f1);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
);
我是 android 开发的新手,所以如果有人能够帮助我,我会很高兴。我已经调查了很多时间来寻找解决方案,但结果并不如我所愿。
我目前的项目:http://cl.ly/3q1f2t1O2Y3j
【问题讨论】:
您是否在 ABS 的 Fragments 示例项目中看到“Tabs and Pager”示例? 【参考方案1】:我明白了!
让我解释一下,您需要在要替换的 Layout 上放置一个 id,我的示例:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/Framelay"
android:layout_
android:layout_ >
<TextView
android:id="@+id/txtSearchTopic"
android:layout_
android:layout_
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="TextView" />
</FrameLayout>
所以我只输入我的:android:id="@+id/Framelay" 然后我可以用这个Id来替换新的fragment,我的意思是这个Layout里面的所有内容都会被新的Fragment替换,我叫DetailFragment。
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
DetailFragment fragment3 = new DetailFragment();
fragmentTransaction.replace(R.id.Framelay, fragment3);
fragmentTransaction.commit();
【讨论】:
当使用 android.R.id.content 而不是 R.id.pager 时,如上所述,它适用于当前视图,但是当执行此代码然后切换到另一个选项卡时,新添加的Fragment 覆盖在另一个 Tab 中显示的 Fragment。 我明白了,你明白了,这是个好问题,我会努力寻找解决方案。 在最初加载的 Fragment 中,我将 id 添加到 LinearLayout 参数中。然后在替换视图时,视图没有被替换,我在新视图下看到了新视图。 我不明白为什么将新视图放在旧视图下,尝试了很多方法并做了同样的事情,我刚刚得到了一个运行良好的示例项目,也许你能比我理解得更好,见github.com/tamsler/android-flash-cards 我有一个更好的解决方案,见4shared.com/rar/zOWrvmyu/ViewpagerandSherlock.html,在每个fragment里面你可以实现Asynctask,看看你能不能看懂。以上是关于ActionBarSherlock、ViewPager、TabsAdapter 嵌套选项卡片段的主要内容,如果未能解决你的问题,请参考以下文章
ActionBarSherlock:java.lang.NoClassDefFoundError:com.actionbarsherlock.R$styleable
ActionBarSherlock & ShareActionProvider 导致 InflateException