从活动中调用片段中的方法时,菜单项为null

时间:2013-02-19 01:33:53

标签: android android-actionbar android-viewpager menuitem

我的应用在纵向模式下使用ViewPager,在横向上使用双片段布局。

我正试图从AsyncTask开始Fragment ActivityAsyncTask通常是从Actionbar中的菜单项开始的,但我需要从Activity以编程方式启动它。

菜单项是ImageView,我在AsyncTask正在运行时设置动画。我在双片段横向视图中的代码工作正常,但在纵向模式下,我在菜单项上得到NullPointerException

活动

public class Main extends SherlockFragmentActivity
{
    private static List<Integer> mIds;
    private static SparseArray<Fragment> mPageReferenceMap = new SparseArray<Fragment>();

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

        setContentView(R.layout.main);

        mViewPager = (ViewPager)findViewById(R.id.viewpager); //view pager exists, so we are using the portait layout

        if (mViewPager != null)
        {
            mIds = new ArrayList<Integer>();

            mIds.add(0);
            mIds.add(1);
            mIds.add(2);

        }
        else //in landscape
        {           
            ListFragment lf = (ListFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentList);

            if (lf == null)
                lf = new ListFragment();

            DetailFragment df = (DetailFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentDetail);

            if (df == null)
            {
                df = new DetailFragment();
                df.setArguments(getIntent().getExtras());   
            }

            getSupportFragmentManager().beginTransaction().add(R.id.fragmentList, lf).commit();
            getSupportFragmentManager().beginTransaction().add(R.id.fragmentDetail, df).commit();

        }

        final MyFragmentPagerAdapter fpa = (MyFragmentPagerAdapter)mViewPager.getAdapter();
        ListFragment lf2 = (ListFragment)fpa.getFragment(0);

        //this works if I use:
        //(ListFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentList);

        lf2.RunTask();
    }       

    private static class MyFragmentPagerAdapter extends FragmentStatePagerAdapter  {  

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

        @Override  
        public Fragment getItem(int index) {        
            if (index == 0)
            {
                ListFragment lf = ListFragment.newInstance();
                mPageReferenceMap.put(index, lf);
                return lf;
            }
            else
            {
                DetailFragment df = DetailFragment.newInstance(mIds.get(index-1));
                mPageReferenceMap.put(index, df);
                return df;
        }  

        public Fragment getFragment(int key) {
            return mPageReferenceMap.get(key);
        }

        public void destroyItem(View container, int position, Object object) {
            super.destroyItem(container, position, object);
            mPageReferenceMap.remove(position);
        }

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

片段

public class ListingFragment extends SherlockListFragment
{
    private MenuItem refreshItem;

    public static ListingFragment newInstance() {

        ListingFragment lf = new ListingFragment();

        return lf;
    }

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

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

        return inflater.inflate(R.layout.listing_layout, container, false);
    }

    private void StartAnimation() {
       final LayoutInflater inflater = (LayoutInflater)getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       final ImageView ivRefresh = (ImageView)inflater.inflate(R.layout.refresh_view, null);

       final Animation rotation = AnimationUtils.loadAnimation(getActivity(), R.anim.refresh);
       ivRefresh.startAnimation(rotation);

        //this is null
       refreshItem.setActionView(ivRefresh);
    }

    public void StopAnimation()
    {
        if (refreshItem != null && refreshItem.getActionView() != null) 
        {
            refreshItem.getActionView().clearAnimation();
            refreshItem.setActionView(null);
        }
    }

    public void RunTask()
    {
        new GetItems().execute();
    }

    private class GetItems extends AsyncTask<Void, Void, Void> 
    {
        @Override
        protected void onPreExecute() 
        {
          StartAnimation();
        }

        @Override
        protected Void doInBackground(Void... unused)
        {
            ...
        }

        protected void onPostExecute(final Void unused)
        {
            StopAnimation();
        }
    }

    @Override
    public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
        inflater.inflate(R.menu.keyword_menu, menu);

        refreshItem = menu.findItem(R.id.get);

        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) 
    {
        if (item.getItemId() == R.id.get) {
            gi = new GetItems(getActivity(), null);
            gi.execute();
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }
}   

1 个答案:

答案 0 :(得分:0)

我认为以下链接为您提供了如何避免nullpointer异常的答案。 Fragment的实例可以在任何时候由系统重新创建,这就是为什么“持有对它们的引用”并不容易。你必须使用fragmentmanager。

adapter instance gone in fragment with listview