对于ActionBarSherlock,我想要(Action Bar)Tabs + Pager。我在该寻呼机容器中使用Fragments。我已经得到了http://actionbarsherlock.com/的示例,但是当我点击第一个片段中的一个listitem时,我无法设法在该寻呼机容器中获取详细信息片段。
不可能有这样的事情:
带标签和寻呼机容器的活动
然后片段A不可见,只有片段B可见,但也可见所有标签。
目前我认为在点击片段A中的某些内容后,只能启动一个新活动(可以在其中包含片段B)。
答案 0 :(得分:15)
这是我的(Tabs + Fragment + ViewPager)解决方案,它对我来说很有用,我想要的, 希望对你有用
这是xml文件
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="5" />
<FrameLayout
android:id="@+id/fragment_details"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="4.3" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="5" />
<FrameLayout
android:id="@+id/fragment_details"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="4.3" />
</LinearLayout>
这里是MainActivity.java的代码我只发布相关代码,所以你必须管理它
以下是我如何处理细节片段效率不高但工作有点 public class MainActivity extends FragmentActivity implements
DialogInterface.OnDismissListener, TabDataResponder {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
artistTab = getSupportActionBar().newTab().setText(
R.string.tab_name_artist);
albumTab = getSupportActionBar().newTab().setText(
R.string.tab_name_album);
songTab = getSupportActionBar().newTab().setText(
R.string.tab_name_songs);
map = new HashMap<String, Integer>();
mViewPager = (ViewPager) findViewById(R.id.pager);
FrameLayout deatil = (FrameLayout) findViewById(R.id.fragment_details);
mDualPane = (deatil != null) && (deatil.getVisibility() == View.VISIBLE);
mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);
if (savedInstanceState != null) {
flag = true;
index = savedInstanceState.getInt("index");
}
setUpTabView();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("index", getSupportActionBar()
.getSelectedNavigationIndex());
}
private void setUpTabView() {
mTabsAdapter.addTab(artistTab, ArtistFragment.class, null);
mTabsAdapter.addTab(albumTab, AlbumFragment.class, null);
mTabsAdapter.addTab(songTab, SongFragment.class, null);
getSupportActionBar().setSelectedNavigationItem(index);
}
public static class TabsAdapter extends FragmentPagerAdapter implements
ViewPager.OnPageChangeListener, ActionBar.TabListener {
private FragmentActivity mContext;
private ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<String> mTabs = new ArrayList<String>();
private TabDataResponder responder;
public TabsAdapter(FragmentActivity activity, ActionBar actionBar,
ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = actionBar;
mViewPager = pager;
// TabDataResponder is an interface which is implemented in MainActivity
// You can find implementation @ the last
responder = (TabDataResponder) activity;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
//I have used map to save state of the fragment
map.put(SongFragment.TYPE_FRAGMENT.trim(), 0);
map.put(AlbumFragment.TYPE_FRAGMENT.trim(), 0);
map.put(ArtistFragment.TYPE_FRAGMENT.trim(), 0);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
mTabs.add(clss.getName());
// mArgs.add(args);
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
return Fragment
.instantiate(mContext, mTabs.get(position), /*
* mArgs.get(
* position)
*/null);
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Log.i(TAG, "PageSelected....");
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrollStateChanged(int state) {
Log.i(TAG, "ScrollSateChanged....");
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
String a = null;
if (mDualPane) {
a = mTabs.get(tab.getPosition());
responder.loadData(a, map.get(a));
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Log.i(TAG, "Tab is released now....");
}
}
@Override
public void onDismiss(DialogInterface dialog) {
setUpTabView();
}
//This interface must be call from fragment class
//@ the time of event you want to show detail
// pass the class name in the type argument using class.getName() method
@Override
public void loadData(String type, int index) {
DetailFragment viewer = (DetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_details);
if (mDualPane) {
if (viewer == null || viewer.getShownIndex() != index
|| viewer.getTypeFragment() != type) {
DetailFragment df = DetailFragment.newInstance(index, type);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_details, df)
.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
map.put(type.trim(), index);
}
} else {
Intent intent = new Intent();
intent.setClass(MainActivity.this, DetailActivity.class);
intent.putExtra("index", index);
intent.putExtra("type", type);
startActivity(intent);
}
}
}
public class MainActivity extends FragmentActivity implements
DialogInterface.OnDismissListener, TabDataResponder {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
artistTab = getSupportActionBar().newTab().setText(
R.string.tab_name_artist);
albumTab = getSupportActionBar().newTab().setText(
R.string.tab_name_album);
songTab = getSupportActionBar().newTab().setText(
R.string.tab_name_songs);
map = new HashMap<String, Integer>();
mViewPager = (ViewPager) findViewById(R.id.pager);
FrameLayout deatil = (FrameLayout) findViewById(R.id.fragment_details);
mDualPane = (deatil != null) && (deatil.getVisibility() == View.VISIBLE);
mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);
if (savedInstanceState != null) {
flag = true;
index = savedInstanceState.getInt("index");
}
setUpTabView();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("index", getSupportActionBar()
.getSelectedNavigationIndex());
}
private void setUpTabView() {
mTabsAdapter.addTab(artistTab, ArtistFragment.class, null);
mTabsAdapter.addTab(albumTab, AlbumFragment.class, null);
mTabsAdapter.addTab(songTab, SongFragment.class, null);
getSupportActionBar().setSelectedNavigationItem(index);
}
public static class TabsAdapter extends FragmentPagerAdapter implements
ViewPager.OnPageChangeListener, ActionBar.TabListener {
private FragmentActivity mContext;
private ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<String> mTabs = new ArrayList<String>();
private TabDataResponder responder;
public TabsAdapter(FragmentActivity activity, ActionBar actionBar,
ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = actionBar;
mViewPager = pager;
// TabDataResponder is an interface which is implemented in MainActivity
// You can find implementation @ the last
responder = (TabDataResponder) activity;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
//I have used map to save state of the fragment
map.put(SongFragment.TYPE_FRAGMENT.trim(), 0);
map.put(AlbumFragment.TYPE_FRAGMENT.trim(), 0);
map.put(ArtistFragment.TYPE_FRAGMENT.trim(), 0);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
mTabs.add(clss.getName());
// mArgs.add(args);
mActionBar.addTab(tab.setTabListener(this));
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
return Fragment
.instantiate(mContext, mTabs.get(position), /*
* mArgs.get(
* position)
*/null);
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
Log.i(TAG, "PageSelected....");
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onPageScrollStateChanged(int state) {
Log.i(TAG, "ScrollSateChanged....");
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
String a = null;
if (mDualPane) {
a = mTabs.get(tab.getPosition());
responder.loadData(a, map.get(a));
}
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
Log.i(TAG, "Tab is released now....");
}
}
@Override
public void onDismiss(DialogInterface dialog) {
setUpTabView();
}
//This interface must be call from fragment class
//@ the time of event you want to show detail
// pass the class name in the type argument using class.getName() method
@Override
public void loadData(String type, int index) {
DetailFragment viewer = (DetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_details);
if (mDualPane) {
if (viewer == null || viewer.getShownIndex() != index
|| viewer.getTypeFragment() != type) {
DetailFragment df = DetailFragment.newInstance(index, type);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fragment_details, df)
.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
map.put(type.trim(), index);
}
} else {
Intent intent = new Intent();
intent.setClass(MainActivity.this, DetailActivity.class);
intent.putExtra("index", index);
intent.putExtra("type", type);
startActivity(intent);
}
}
}
不要将tab的状态保存在它们各自的片段中会发生冲突,我们已经在这里做了
答案 1 :(得分:2)
编辑:
太快欢呼了。现在details_container不是viewpager,我不能用它来“滑动标签”。
首先是两个FrameLayouts:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fadingEdge="none" >
<FrameLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
<FrameLayout
android:id="@+id/details_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
然后动态替换片段:
// Create new fragment and transaction
Fragment detailsFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment container view with this fragment
// and add the transaction to the back stack
transaction.replace(R.id.details_container, detailsFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
非常简单,我不明白为什么我需要花费数小时来解决这个问题。
答案 2 :(得分:0)
我仍然没有找到一个可能加载片段的Pager容器并且还保留(ActionBar)选项卡的可能性。然而,我发现了一个非常肮脏的解决方案来实现这一点,启动强度(带有选项卡的主要活动)并在后退按钮不再需要它时完成之前的操作。
我改编了ABS: Support Demos - Tabs和Pager的代码。但是它真的很脏:
Tab2下的LoaderCursorSupport.CursorLoaderListFragment
@Override public void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = new Intent();
intent.setClass(getActivity(), ActionBarTabsPager.class);
intent.putExtra("index", position);
intent.putExtra("fragment", "details");
intent.putExtra("tab", 1);
ActionBarTabsPager.mPreviousActivity = getActivity();
startActivity(intent);
ActionBarTabsPager(带标签的主要活动)
public class ActionBarTabsPager extends FragmentActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
static Activity mPreviousActivity;
static Activity mActivity;
static int mTabPosition = -1;
static Boolean mTabRefreshed = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actionbar_tabs_pager);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = getSupportActionBar().newTab().setText("Tab 1");
ActionBar.Tab tab2 = getSupportActionBar().newTab().setText("Tab 2");
ActionBar.Tab tab3 = getSupportActionBar().newTab().setText("Tab 3");
ActionBar.Tab tab4 = getSupportActionBar().newTab().setText("Tab 4");
String fragment = "";
try {
Bundle bundle = this.getIntent().getExtras();
fragment = bundle.getString("fragment");
mTabPosition = bundle.getInt("tab");
} catch (Exception ex) {
}
mViewPager = (ViewPager) findViewById(R.id.pager);
mTabsAdapter = new TabsAdapter(this, getSupportActionBar(), mViewPager);
mTabsAdapter.addTab(tab1, FragmentStackSupport.CountingFragment.class);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ECLAIR) {
mTabsAdapter.addTab(tab2, FragmentStackSupport.CountingFragment.class);
mTabsAdapter.addTab(tab3, FragmentStackSupport.CountingFragment.class);
mTabsAdapter.addTab(tab4, FragmentStackSupport.CountingFragment.class);
} else {
if (!fragment.contains("details")) {
mTabsAdapter.addTab(tab2, LoaderCursorSupport.CursorLoaderListFragment.class);
} else {
mTabsAdapter.addTab(tab2, ExampleFragment.class);
}
mTabsAdapter.addTab(tab3, LoaderCustomSupport.AppListFragment.class);
mTabsAdapter.addTab(tab4, LoaderThrottleSupport.ThrottledLoaderListFragment.class);
}
if (savedInstanceState != null) {
getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt("index"));
}
if (mTabPosition > -1) {
mTabsAdapter.setPrimaryItem(mTabPosition);
mActivity = this;
}
}
在这个类里面有一个TabsAdapter
public static class TabsAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<String> mTabs = new ArrayList<String>();
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mTabPosition > -1 && mTabRefreshed) {
int tabPosition = tab.getPosition();
if (mTabPosition != tabPosition) {
if (mPreviousActivity != null) {
mPreviousActivity.finish();
mTabRefreshed = false;
mPreviousActivity = null;
mTabPosition = -1;
Intent intent = new Intent();
intent.setClass(mContext, ActionBarTabsPager.class);
intent.putExtra("fragment", "home");
intent.putExtra("tab", tabPosition);
mActivity.startActivity(intent);
mActivity.finish();
}
}
}
mViewPager.setCurrentItem(tab.getPosition());
}
这可以更简单吗?或者我应该放弃使用Tabs和片段历史记录?这是在Android 3.0之前使用ActivityGroups和Activities完成的,但似乎无法通过片段完成。
答案 3 :(得分:0)
我在听到...... https://github.com/UweTrottmann/SeriesGuide
时找到了相同实现的另一个好例子在com.battlelancer.seriesguide.ui包中的示例中
你可以找到UpcomingRecentActivity.java和UpcomingFragment.java
和布局coming_multipan.xml
这个例子对我有用......
我在为不同的标签添加不同的内容时遇到了一个问题,它给了我类 - 强制转换异常
所以我实现了一个常见的detalFragment类,并在onCreateView方法中创建了单独的布局
但我发现的唯一一个问题是布局在切换时没有改变,可能需要通过实现一些监听器来实现
当我找到答案时,我会告诉你的。