1

私のカレンダー アプリケーションでは、ActionBarSherlock を使用して 2 つのタブ (1) カレンダー 2) コンバーターを表示しています。ActionBar メニュー項目のクリック イベントで、SlidingMenuドロワーを使用してその月のイベントの概要を表示しています。

カレンダー タブ専用の viewpager を使用したいので、次のように実装しました。

Main.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;
        }

    }
}

CalendarFragment.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()がnullであるためであることが示されます。

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 に答える