1

在我的日历应用程序中,我使用 ActionBarSherlock 来显示两个选项卡 - 1) 日历 2) 转换器。在 ActionBar 菜单项的单击事件中,我使用SlidingMenu抽屉来显示该月的事件摘要。

我想专门为日历选项卡使用 viewpager,并且我已经通过这种方式实现了它:

主.java:

public class BaseActivity extends SlidingSherlockFragmentActivity 
{

    private ViewPager pager;
    CalendarFragmentPagerAdapter mPagerAdapter;
    private static final int MONTHS_LIMIT = 5;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 

        setTitle(R.string.app_name);

        setContentView(R.layout.main);
        getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.main, new CalendarFragment())
        .commit();

        setBehindContentView(R.layout.content_frame);
        getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.content_frame, new EventsSummary())
        .commit();

        setSlidingActionBarEnabled(false);

        final ActionBar bar = getSupportActionBar();
        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        bar.setHomeButtonEnabled(true);

        ActionBar.Tab calendar = bar.newTab();
        ActionBar.Tab converter = bar.newTab();

        calendar.setText(this.getResources().getString(R.string.calendar));
        converter.setText(this.getResources().getString(R.string.converter));

        calendar.setTabListener(new MyTabListener());
        converter.setTabListener(new MyTabListener());

        bar.addTab(calendar);
        bar.addTab(converter);

        // customize the SlidingMenu
        SlidingMenu sm = getSlidingMenu();
        sm.setShadowWidthRes(R.dimen.shadow_width);
        sm.setShadowDrawable(R.drawable.shadow);
        sm.setBehindOffsetRes(R.dimen.actionbar_home_width);
        sm.setSlidingEnabled(false);

        mPagerAdapter = new CalendarFragmentPagerAdapter(getSupportFragmentManager());
        pager = (ViewPager) this.findViewById(R.id.viewpager);
        pager.setAdapter(mPagerAdapter);
        pager.setCurrentItem(MONTHS_LIMIT / 2);


    }


    private class MyTabListener implements ActionBar.TabListener
    {

        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            if(tab.getPosition()==0)
            {
                CalendarFragment frag = new CalendarFragment();
                ft.replace(R.id.main, frag);
            }
            else
            {
                ConverterFragment frag = new ConverterFragment();
                ft.replace(R.id.main, frag);
            }
        }
        @Override
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            // TODO Auto-generated method stub
        }
        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            // TODO Auto-generated method stub
        }
     }

    public boolean onOptionsItemSelected(MenuItem item) {
        Intent newActivity;
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.menu_slidingmenu:
                toggle();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }



    public class CalendarFragmentPagerAdapter extends FragmentPagerAdapter {

        public CalendarFragmentPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            CalendarFragment fragment = new CalendarFragment();
            Bundle args = new Bundle();
            args.putInt("offset", position - MONTHS_LIMIT / 2);
            fragment.setArguments(args);
            return fragment;
        }

        @Override
        public int getCount() {
            return MONTHS_LIMIT;
        }

    }
}

日历片段.java:

public class CalendarFragment extends Fragment
{

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            Bundle args = getArguments();
            int offset = args.getInt("offset"); //throws NullPointerException
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View v =  inflater.inflate(R.layout.simple_calendar_view, container, false);

            .....

            return v;
        }

        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putBoolean("dummy", true);
        }


}

问题出在 CalendarFragment 中的这一行:

int offset = args.getInt("offset");

它抛出错误NullPointerException,调试显示这是因为Bundle args = getArguments()为空。

我试图将断点放在 PagerAdapter 中的这一行:

Bundle args = new Bundle();

但它永远不会到达这里并且应用程序崩溃并抛出NullPointerException.

我哪里错了?

4

1 回答 1

0

这里

getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.main, new CalendarFragment())
        .commit();

和这里

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    if (tab.getPosition() == 0) {
        CalendarFragment frag = new CalendarFragment();
        ft.replace(R.id.main, frag);
    } else {
        ConverterFragment frag = new ConverterFragment();
        ft.replace(R.id.main, frag);
    }
}

您只是在创建一个没有任何参数的空 CalendarFragment 实例。

因此,您的活动启动,创建一个没有参数的空片段,然后在尝试获取这些时崩溃

于 2013-01-19T21:46:44.587 回答