Android Actionbarsherlock + 标签 + 多片段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10082163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Actionbarsherlock + tabs + multi fragments?
提问by Marckaraujo
I′ve tried so hard to get actionbarsherlock + tabs + fragments working.
我已经非常努力地让 actionbarsherlock + tabs + fragment 工作。
I only can make this set to work as static, I would like to create this like android market app (swipe movement).
我只能让这个设置作为静态工作,我想创建这个像 android 市场应用程序(滑动移动)。
I get stuck when you need to inflate a layout with multi fragments inside.
当您需要为内部包含多个片段的布局膨胀时,我会卡住。
In Support4demos, I got FragmentsTabsPager as example to follow.
在 Support4demos 中,我以 FragmentsTabsPager 为例。
采纳答案by davidcesarino
You need the right libraries to implement what you want.
您需要正确的库来实现您想要的。
Basically, a ViewPager
library is what is missing from you. My suggestions:
基本上,ViewPager
图书馆就是你所缺少的。我的建议:
1. ActionbarSherlock
1.ActionbarSherlock
It's so dead-easy to work with that I won't explain it.
它非常容易使用,我不会解释它。
2. ViewPagerExtensions
2. ViewPagerExtensions
You can find it here. Download the ZIP files and create a new project from it.
你可以在这里找到它。下载 ZIP 文件并从中创建一个新项目。
I only can make this set to work as static, I would like to create this like android market app (swype movement).
我只能让这个设置作为静态工作,我想创建这个像 android 市场应用程序(swype 运动)。
Implement com.astuetz.viewpager.extensions.SwipeyTabsView
from this project. There are easy-to-follow examples. it does exactly what you want. There are even other tab styles to choose from (including the new People tab that comes with ICS). Besides, it's very easy to style it to match your app identity.
com.astuetz.viewpager.extensions.SwipeyTabsView
从这个项目实施。有易于遵循的示例。它完全符合您的要求。甚至还有其他选项卡样式可供选择(包括 ICS 附带的新人员选项卡)。此外,可以很容易地将其设置为与您的应用程序标识相匹配的样式。
3. FragmentPagerAdapter
3. FragmentPagerAdapter
Finally, that class from the support library (v4).
最后,来自支持库 (v4) 的那个类。
Good luck, and be free to ask me if you need more help.
祝你好运,如果您需要更多帮助,请随时问我。
You don't need to override instantiateItem
in FragmentPagerAdapter
if you're using what I suggested. You only need to
如果您使用的是我建议的内容instantiateItem
,FragmentPagerAdapter
则无需覆盖。你只需要
- Provide a constructor with a
FragmentManager
and call the super implementation; - Override
getCount
to return the number of fragments in your pager, and getItem
, which is what you'll use to return your fragments for creation.
- 提供一个带有 a 的构造函数
FragmentManager
并调用 super 实现; - 覆盖
getCount
以返回寻呼机中的片段数,以及 getItem
,这是您将用于返回片段以进行创建的内容。
This is an example from code I have here (a full working, production example). It's an inner class to the activity that implements the pager:
这是我这里的代码示例(一个完整的生产示例)。它是实现寻呼机的活动的内部类:
static class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return 2;
}
@Override
public Fragment getItem(int position) {
Fragment f;
switch(position) {
case 0:
f= new ItemSalesDataFragment();
break;
case 1:
f= new DepartmentChooserFragment();
break;
default:
throw new IllegalArgumentException("not this many fragments: " + position);
}
return f;
}
}
As you can see, this pager handles two 'pages', the left displays sales data. The right one allows the user to select which department. Those are returned in the getItem
method. The proper fragments (you can use whatever Fragments you already have, no modification needed).
如您所见,此寻呼机处理两个“页面”,左侧显示销售数据。右边的允许用户选择哪个部门。这些在getItem
方法中返回。正确的片段(您可以使用任何已有的片段,无需修改)。
As expected, you join all this together by 1) creating an object that instantiate MyFragmentPagerAdapter
, and 2) setting the adapter to your ViewPager
object to be that class that you just instantiated. As you can see, its getItem
method will "give" the pager all the fragments you need. Example:
正如预期的那样,您通过 1) 创建一个实例化的对象MyFragmentPagerAdapter
,以及 2) 将适配器设置为您的ViewPager
对象,使其成为您刚刚实例化的那个类,从而将所有这些连接在一起。如您所见,它的getItem
方法将“给”寻呼机您需要的所有片段。例子:
mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);
Of course, there are other things to do, like creating the tab buttons themselves and joining all this to cross-communicate. I suggest looking at the examples provided in the ViewPagerExtensions ZIP file that you download from GitHub. This is just the answer to the question in your comment. As you can see, it's not that much code using this library.
当然,还有其他事情要做,例如自己创建选项卡按钮并加入所有这些以进行交叉通信。我建议查看您从 GitHub 下载的 ViewPagerExtensions ZIP 文件中提供的示例。这只是您评论中问题的答案。如您所见,使用该库的代码并不多。
回答by Rymnel
I actually managed to get this working without anything more than the ABS library and the support library. Here is my code:
我实际上设法在没有 ABS 库和支持库的情况下完成了这项工作。这是我的代码:
public class ActionBarTabs extends SherlockFragmentActivity {
CustomViewPager mViewPager;
TabsAdapter mTabsAdapter;
TextView tabCenter;
TextView tabText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mViewPager = new CustomViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Home"),
ToolKitFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText("FujiSan"),
FujiFragment.class, null);
}
public static class TabsAdapter extends FragmentPagerAdapter implements
ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
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(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = 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() {
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) {
mActionBar.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);
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
}
You load your tab content based on the following.
您根据以下内容加载选项卡内容。
mTabsAdapter.addTab(bar.newTab().setText("Home"),
YOURFRAGMENTHERE.class, null);
This will give you the lovely "swipey tab" effect, as you refer to it, with ABS, the support library and fragments. ABS really makes this nearly the same as working with the native libraries. I actually copied this code straight from Googles paging tabs example and modified it ever so slightly for ABS.
这将为您提供可爱的“swipey tab”效果,如您所指,带有 ABS、支持库和片段。ABS 确实使这与使用本机库几乎相同。实际上,我直接从 Google 的分页选项卡示例中复制了此代码,并针对 ABS 对其进行了略微修改。
Hope this helps!
希望这可以帮助!
回答by rdshapiro
Lots of examples usually throw an exception (IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first
) when switching back to a previously selected tab.
许多示例IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first
在切换回之前选择的选项卡时通常会抛出异常 ( )。
I like to adapt Google's example with a FragmentStatePageAdapter
instead of a plain FragmentPageAdapter
, which will replace fragments for you and solve this error. Normally this will will destroy fragments that it deems can be removed to save space; override destroyItem(ViewGroup, int, Object)
with an empty block if you want to always hold on to your fragments.
我喜欢用 aFragmentStatePageAdapter
而不是 plain来调整谷歌的例子FragmentPageAdapter
,它会为你替换片段并解决这个错误。通常这会破坏它认为可以移除以节省空间的碎片;destroyItem(ViewGroup, int, Object)
如果您想始终保留片段,请使用空块覆盖。
Here's an example:
下面是一个例子:
public class ActionBarTabs extends SherlockFragmentActivity {
CustomViewPager mViewPager;
TabsAdapter mTabsAdapter;
TextView tabCenter;
TextView tabText;
ActionBar mActionBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mViewPager = new CustomViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
mActionBar = getSupportActionBar();
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mActionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(mActionBar.newTab().setText("Page 1"),
YOURFRAGMENT_A.class, null);
mTabsAdapter.addTab(mActionBar.newTab().setText("Page 2"),
YOURFRAGMENT_B.class, null);
mTabsAdapter.addTab(mActionBar.newTab().setText("Page 3"),
YOURFRAGMENT_C.class, null);
}
public static class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
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(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = 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() {
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) {
mActionBar.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);
}
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
}
Works well with ABS and is relatively simple to implement.
与 ABS 配合良好,实施起来相对简单。