Actionbarsherlock +タブ+フラグメントを機能させるために一生懸命努力しました。
このセットを静的として機能させることしかできません。これをAndroidマーケットアプリ(スワイプ移動)のように作成したいと思います。
複数のフラグメントを内部に含むレイアウトを膨らませる必要がある場合、私は行き詰まります。
Support4demosでは、例としてFragmentsTabsPagerを使用しました。
必要なものを実装するには、適切なライブラリが必要です。
基本的に、ViewPager
ライブラリはあなたに欠けているものです。私の提案:
1。 ActionbarSherlock
それはとても死んでいます-扱いやすいので、私はそれを説明しません。
2。 ViewPagerExtensions
あなたはそれを見つけることができます ここ 。 Zipファイルをダウンロードし、そこから新しいプロジェクトを作成します。
このセットを静的として機能させることしかできません。これをAndroidマーケットアプリ(スワイプムーブメント)のように作成したいと思います。
実装com.astuetz.viewpager.extensions.SwipeyTabsView
このプロジェクトから。わかりやすい例があります。それはまさにあなたが望むことをします。選択できるタブスタイルは他にもあります(ICSに付属する新しい[人]タブを含む)。さらに、アプリのIDに合わせてスタイルを設定するのは非常に簡単です。
3。 FragmentPagerAdapter
最後に、サポートライブラリ(v4)からのそのクラス。
頑張ってください、そしてあなたがもっと助けが必要かどうか私に自由に尋ねてください。
私が提案したものを使用している場合は、instantiateItem
のFragmentPagerAdapter
をオーバーライドする必要はありません。あなただけがする必要があります
FragmentManager
を提供し、スーパー実装を呼び出します。getCount
をオーバーライドして、ページャー内のフラグメントの数を返し、getItem
、これは、作成のためにフラグメントを返すために使用するものです。これは私がここに持っているコードの例です(完全に機能する本番の例)。これは、ページャーを実装するアクティビティの内部クラスです。
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;
}
}
ご覧のとおり、このポケットベルは2つの「ページ」を処理し、左側には販売データが表示されます。正しいものを使用すると、ユーザーはどの部門を選択できます。それらはgetItem
メソッドで返されます。適切なフラグメント(既に持っているフラグメントを使用できます。変更は必要ありません)。
予想どおり、1)MyFragmentPagerAdapter
をインスタンス化するオブジェクトを作成し、2)アダプターをViewPager
オブジェクトに設定して、インスタンス化したばかりのクラスにすることで、これらすべてを結合します。ご覧のとおり、そのgetItem
メソッドは、必要なすべてのフラグメントをページャーに「提供」します。例:
mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);
もちろん、タブボタン自体を作成し、これらすべてを結合して相互通信するなど、他にもやるべきことがあります。 GitHubからダウンロードしたViewPagerExtensionsZipファイルで提供されている例を確認することをお勧めします。これはあなたのコメントの質問に対する答えにすぎません。ご覧のとおり、このライブラリを使用するコードはそれほど多くありません。
私は実際に、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) {
}
}
}
以下に基づいてタブコンテンツをロードします。
mTabsAdapter.addTab(bar.newTab().setText("Home"),
YOURFRAGMENTHERE.class, null);
これにより、ABS、サポートライブラリ、およびフラグメントを使用して、参照どおりに素敵な「スワイプタブ」効果が得られます。 ABSは、これをネイティブライブラリでの作業とほぼ同じにします。私は実際にこのコードをGoogleのページングタブの例から直接コピーし、ABS用に少し変更しました。
お役に立てれば!
多くの例では、通常、以前に選択したタブに戻るときに例外(IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first
)がスローされます。
Googleの例をプレーンなFragmentStatePageAdapter
ではなくFragmentPageAdapter
に適合させるのが好きです。これにより、フラグメントが置き換えられ、このエラーが解決されます。通常、これにより、スペースを節約するために削除できると見なされるフラグメントが破棄されます。フラグメントを常に保持したい場合は、destroyItem(ViewGroup, int, Object)
を空のブロックでオーバーライドします。
次に例を示します。
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) {
}
}
}
ABSでうまく機能し、実装は比較的簡単です。