片段在viewPager.setOnPageChangeListener()中返回null

时间:2015-02-03 21:41:17

标签: java android android-fragments

我有一个名为GuivActivity的主要活动,它使用viewPager在两个片段(listFragment和SearchFragment)之间切换。但是当我尝试在onPageSelected中通过id获取Fragment时,它返回null。

我想在这里做的就是重新启动ListFragment中的加载器,这样每次我回来时都会获得最新的数据。

GuivActivity.java中的

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

        setContentView(R.layout.activity_guiv);

        viewPager = (ViewPager)findViewById(R.id.viewpager);
        indicator = (TitlePageIndicator) findViewById(R.id.titleindicator);
        pagerAdapter = new PagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(pagerAdapter);
        indicator.setViewPager(viewPager);
        indicator.setOnPageChangeListener(listener);
    }
   ViewPager.OnPageChangeListener listener = new ViewPager.SimpleOnPageChangeListener(){
       @Override
       public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

       }
       @Override
       public void onPageSelected(int position) {

           switch (position){
               case 0:
                   FragmentManager fm = getSupportFragmentManager();
                   ListFragment listFragment = (ListFragment) fm.findFragmentById(R.id.list_fragment_id);

               case 1:

               default:
                   break;
           }
       }

       @Override
       public void onPageScrollStateChanged(int state) {

       }
   };
ListFragment.java中的

@Override
public void onResume() {
    Message.message(mContext,"on resumed called");
    getLoaderManager().restartLoader(LIST_LOADER,null,this);
    super.onResume();
}
GuivActivity.xml中的

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


<com.viewpagerindicator.TitlePageIndicator
    android:id="@+id/titleindicator"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent" />

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="1"
    android:background="@android:color/white"/>

片段adatper中的

 @Override
public Fragment getItem(int position) {
    switch(position){
        case 0:
            return new ListFragment();
        case 1:
            return new SearchFragment();
        default:
            break;
    }

    return null;
}

3 个答案:

答案 0 :(得分:3)

解决方案1 ​​

ListFragment listFragment = (ListFragment) pagerAdapter.instantiateItem(viewPager, position)

解决方案2 这是一个黑客

ListFragment listFragment = (ListFragment) getSupportFragmentManager().findFragmentByTag(
       "android:switcher:" + R.id.viewpager + ":" + viewPager.getCurrentItem());

注意 但我建议你使用FragmentPagerAdapter。它会比PageAdapter

给你更多的控制权

答案 1 :(得分:1)

为什么不调用您的片段类来获取视图?然后在片段管理器上调用add。这种方式更加清晰,更容易实现“后退”按钮。

public void displayView(int position, Bundle arguments) {

         Fragment fragment = null;
        switch (position) {
            case 0:
                fragment = new ListFragment();
                break;
            case 1:               
                break;          
            default:
                break;
        }

        if (fragment != null) {
            FragmentManager fragmentManager = getFragmentManager();

            String backStateName = fragment.getClass().getName();
            boolean fragmentPopped = fragmentManager.popBackStackImmediate (backStateName, 0);

            if (!fragmentPopped&&fragmentManager.findFragmentByTag(backStateName) == null){ //fragment not in back stack, create it.
                FragmentTransaction ft =fragmentManager.beginTransaction();
                ft.replace(R.id.frame_container, fragment,backStateName);
                ft.addToBackStack(backStateName);
                ft.commit();

            }

            // update selected item and title, then close the drawer
            mDrawerList.setItemChecked(position, true);
            mDrawerList.setSelection(position);
            setTitle(navMenuTitles[position]);
            mDrawerLayout.closeDrawer(mDrawerList);
            if (position==0){

            }
        } else {
            // error in creating fragment
            Log.e("MainActivity", "Error in creating fragment");
        }
    }

答案 2 :(得分:0)

巧合的是,我今天正在解决同样的问题。它们的关键是像这样实例化适配器:

  mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
      super.setPrimaryItem(container, position, object);

      mCurrentFragment = (Fragment) object;
    }
  };

现在,每当视图寻呼机切换到另一个片段时(即使在第一个加载和屏幕方向上),该片段也会被加载到mCurrentFragment字段变量中(不要忘记声明它)。

优点:您不必使用内部片段ID。我刚试过它。它非常优雅。

缺点:我不知道。

注意:如果您需要,也不要忘记在您的分页片段中实施onSaveInstanceState(Bundle)onViewStateRestored(Bundle)基于真实故事。