4

我一直在尝试测试如何将所有这些东西混合在一起,但我遇到了问题!!我只想要一个使用 ActionBar.Tab 的具有三个选项卡的应用程序。例如,此选项卡可以是动作、冒险和动画类型的电影,用户可以在选项卡中滑动,因此它将使用 ViewPager,每个选项卡将显示该类型的电影列表。没有必要拥有三个不同的片段类,因为所有选项卡的格式都相同,只是一个简单的列表。我遇到了问题,因为当我选择第二个选项卡时,onPageSelected 的位置是 1,

mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mCollectionPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
     public void onPageSelected(int position) {
        mActionBar.setSelectedNavigationItem(position);
     }
});

这会导致在 CollectionPagerAdapter 类中调用 public Fragment getItem(int i) 方法,但是 i 的值是 2 NOT 1,所以它会调用值为 2 NOT 1 的 TabFragment 类的 createView,所以 tabs没有刷新成功。

任何帮助将不胜感激!

创建选项卡的代码,

// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mCollectionPagerAdapter.getCount(); i++) {
        mActionBar.addTab(mActionBar.newTab()
            .setText(mGenres.get(i).getName()) 
            .setTabListener(this));

        //Let's request the movies for the first three genres
        new GetMoviesByGenre().execute(mGenres.get(i).getId());         
}

选择选项卡时,

@Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction arg1) {

//Let's update the dataset for the selected genre
TabFragment fragment = 
      (TabFragment) getSupportFragmentManager().findFragmentByTag(
                   "android:switcher:"+R.id.pager+":"+tab.getPosition());
     if(fragment != null)  // could be null if not instantiated yet
     {
        if(fragment.getView() != null) 
        {
           fragment.updateDisplay(tab.getPosition()); // do what updates are required
        }
     }

  mViewPager.setCurrentItem(tab.getPosition());
}

CollectionPageAdapter 类

public class CollectionPagerAdapter extends FragmentPagerAdapter {

final int NUM_ITEMS = 3; // number of tabs

List<Fragment> fragments = new ArrayList<Fragment>();

public Fragment getItem(int pos) {
  return fragments.get(pos);
}

public void addFragment(Fragment f) {
  fragments.add(f);
}

public CollectionPagerAdapter(FragmentManager fm) {
    super(fm);

    //Let's add  the fragments
    for (int i=0;i<NUM_ITEMS;i++)
    {
        Fragment fragment = new TabFragment();
        Bundle args = new Bundle();
        args.putInt(TabFragment.ARG_OBJECT, 0);
        fragment.setArguments(args);
        addFragment (fragment);
    }
}

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

}

TabFragment 类

public class TabFragment extends ListFragment {

public static final String ARG_OBJECT = "object";

private MoviesAdapter m_Adapter;
private ArrayList <Movie> mMovies = new ArrayList<Movie>();

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

  // you only need to instantiate these the first time your fragment is
  // created; then, the method above will do the rest
  if (m_Adapter == null) {
      m_Adapter = new MoviesAdapter(getActivity(), mMovies);
  }
  setListAdapter(m_Adapter);
}

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

    int position = getArguments().getInt(ARG_OBJECT); // to check is the right fragment
    View rootView = inflater.inflate(R.layout.tabs, container, false);
    return rootView;
}

public void updateDisplay (int type)
{
     GlobalVars gv = (GlobalVars)getActivity().getApplicationContext();

    switch (type)
    {
        case 0:
            mMovies = gv.getActionMovies();
            break;
        case 1:
            mMovies = gv.getAdventureMovies();
            break;
        case 2:
            mMovies = gv.getAnimationMovies();
            break;
    }

    m_Adapter.notifyDataSetChanged();
}

}

我没有做错什么,我猜是碎片搞砸了,因为当我按下第二个选项卡时,第一个选项卡中的数据会更新,依此类推......

谢谢!

4

3 回答 3

3

我没有使用 CollectionPageAdapter,而是改为使用 ViewPager 的 Android 文档中显示的 TabsAdapter 类它可以工作!

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>();

private final List<Fragment> fragments = new ArrayList<Fragment>();

static final class TabInfo {
    private final Class<?> clss;
    private final Bundle args;

    TabInfo(Class<?> _class, Bundle _args) {
        clss = _class;
        args = _args;
    }
}

public TabsAdapter(FragmentActivity activity, ViewPager pager) {
    super(activity.getSupportFragmentManager());
    mContext = activity;
    mActionBar = activity.getActionBar();
    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 int getCount() {
    return mTabs.size();
}

@Override
public int getItemPosition(Object object) {
    return POSITION_NONE;
}

@Override
public Fragment getItem(int position) {

    TabInfo info = mTabs.get(position);
    Fragment fr = Fragment.instantiate(mContext, info.clss.getName(), info.args);
    //addFragment (fr, position);
    return  fr;

}

public void addFragment(Fragment f, int location) {

    if (fragments.size() == 0)
        fragments.add(f);
    else
        fragments.add(location, f);
  }

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}

@Override
public void onPageSelected(int position) {
    mActionBar.setSelectedNavigationItem(position);
}

@Override
public void onPageScrollStateChanged(int state) {
}

@Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
    Object tag = tab.getTag();
    for (int i=0; i<mTabs.size(); i++) {
        if (mTabs.get(i) == tag) {
            updateDatasetMovies (i);
            mViewPager.setCurrentItem(i);
        }
    }
}



@Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
    // TODO Auto-generated method stub

}

@Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
    // TODO Auto-generated method stub

}


public void updateDatasetMovies (int pos)
{
    //Let's update the dataset for the selected genre
    TabFragment fragment = 
          (TabFragment) ((FragmentActivity)mContext).getSupportFragmentManager().findFragmentByTag(
                       "android:switcher:"+R.id.pager+":"+pos);

    //TabFragment fragment = (TabFragment) getItem(pos);
    if(fragment != null)  // could be null if not instantiated yet
      {
         if(fragment.getView() != null) 
         {
            // no need to call if fragment's onDestroyView() 
            //has since been called.
            fragment.updateDisplay(pos); // do what updates are required
         }
      }

}

}`

于 2013-01-06T15:31:36.103 回答
1

我同意 nirvik 的观点,但是有一个关键的改进是应该做的。这个实现有一个缺陷——当滑动到下一个片段时,会调用 onPageSelected 方法,然后通过调用 mActionBar.setSelectedNavigationItem(position); 来调用 onTabSelected 方法。这会导致动画闪烁。这:

viewPager.setCurrentItem(i);

应该替换为:

if(i != viewPager.getCurrentItem()) {
     viewPager.setCurrentItem(i);
}

从而实现平稳过渡。

于 2013-03-22T12:47:43.207 回答
0

您可以尝试在您的代码中包含以下代码FragmentPagerAdapter,看看这是否解决了问题。

public int getItemPosition(Object object) {
    return POSITION_NONE;
}

您也可以尝试使用FragmentStatePagerAdapter.

于 2013-01-06T05:09:46.243 回答