我用 ViewPager 和 TabsAdapter 实现了一个 ActionBarSherlock。在我尝试在片段之间进行通信之前,它工作正常。
我的应用程序中有 3 个选项卡,我可以毫无问题地单击每个选项卡,但是当通过界面进行通信时,在三个选项卡中的两个选项卡中,我的选项卡中的一个片段为空。当我选择一个菜单项时会发生这种情况。我想选择一个菜单项来传达给 ViewPager 中的所有片段。但是,当我在 tab[0] 中时,tab[2] 为 null,但 tabs[0] 和 tab[1] 不为 null。当我在 tab[2] 中时,tab[0] 为 null,但 tab[1] 和 tab[2] 不为 null。但是,当我在 tab[1] 中时,没有片段为空。
当我单击每个选项卡时,所有片段都可见。这不是问题。
编码:
public class GPSTrackingActivity extends SherlockFragmentActivity implements DistanceFragment.OnCoordinatesAddedListener, ReportsFragment.ReportStartDateListener
{
long insertedID = 0;
private Menu menu;
//for shared preferences
private static final String KEY_UNITS = "units";
private static final String KEY_START_POSITION = "start";
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
String TAG = "GPSTrackingActivity";
//set 0 for miles, 1 for kilometers
int mMilesOrKilometers = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
//create a new ViewPager and set to the pager we have created in Ids.xml
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setNavigationMode ( ActionBar . NAVIGATION_MODE_TABS );
//if user has previous settings, get them from shared prefs.
getSharedPrefs();
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(actionBar.newTab().setText(" Track").setIcon(R.drawable.browser_compass_icon),
DistanceFragment.class, null);
mTabsAdapter.addTab(actionBar.newTab().setText(" Trips").setIcon(R.drawable.folder_chart_icon),
TripsFragment.class, null);
mTabsAdapter.addTab(actionBar.newTab().setText(" Report").setIcon(R.drawable.mail_compose_icon),
ReportsFragment.class, null);
}
/* set the units of measurement for all the fragments
*/
public void ChangeUnitsOfMeasure() {
try {
DistanceFragment DistanceFrag = (DistanceFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":0");
if (DistanceFrag != null && DistanceFrag.getView() != null) {
Log.d(TAG,"Class=" + DistanceFrag.getClass());
Log.d(TAG,"Found the Distance Fragment");
DistanceFrag.ClearData();
DistanceFrag.setMileOrKilometers(mMilesOrKilometers);
}
TripsFragment TripsFrag = (TripsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":1");
if (TripsFrag != null && TripsFrag.getView() != null) {
Log.d(TAG,"Class=" + TripsFrag.getClass());
if (TripsFrag.getClass() == TripsFragment.class) {
Log.d(TAG,"Found the Trips Fragment");
TripsFrag.setMileOrKilometers(mMilesOrKilometers);
}
}
ReportsFragment ReportsFrag = (ReportsFragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":2");
if (ReportsFrag != null && ReportsFrag.getView() != null) {
Log.d(TAG,"Class=" + ReportsFrag.getClass());
Log.d(TAG,"Found the Reports Fragment");
ReportsFrag.setMileOrKilometers(mMilesOrKilometers);
}
}
//in case we change the getCurrentItem() value to anything other than 1
//would expect a ClassCastException
catch (Exception e) {
Log.d(TAG,String.valueOf(e));
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
//check selected menu item
switch (item.getItemId()) {
case R.id.miles:
mMilesOrKilometers = 0;
ChangeUnitsOfMeasure();
return true;
case R.id.kilometers:
mMilesOrKilometers = 1;
ChangeUnitsOfMeasure();
return true;
//quit program
case R.id.menu_quit:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//called from ReportsFragment
public void getCurrentIdOfFragment() {
int mCurrentItem = mViewPager.getCurrentItem();
Log.d(TAG,"Current View Page=" + String.valueOf(mCurrentItem));
}
// create TabsAdapter to create tabs and behavior
public 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>();
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 void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
@Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
mActionBar.setSelectedNavigationItem(position);
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
@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) {
// TODO Auto-generated method stub
}
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
//Fragment mFragment = Fragment.instantiate(mContext, info.clss.getName(), info.args);
return (Fragment) Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public int getCount() {
return mTabs.size();
}
}
}
由于选择了菜单项,当我调用 ChangeUnitsOfMeasure() 函数时,这一切都发生了。我知道片段为空,因为我在调用片段中的函数之前测试片段是否为空。我的 LogCat(请参阅代码)报告仅显示片段 [0] 和 [1] 或片段 [1] 和 [2] 或片段 [0]、[1] 和 [2],具体取决于我所在的选项卡.
真是奇怪的行为!