4

我有一个父SherlockFragmentActivity类,其中包含ViewPager,里面有 4 个片段。
其中之一从SherlockListFragment扩展,我想通过单击它的选项卡将其滚动到顶部。

MainActivity类:

public class MainActivity extends SherlockFragmentActivity  {

ViewPager viewPager;
TabAdapter tabAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    setTheme(Constants.THEME);

    viewPager = new ViewPager(this);
    viewPager.setId(R.id.pager);
    viewPager.setBackgroundResource(R.color.background_color);

    tabAdapter = new TabAdapter(this,viewPager);

    super.onCreate(savedInstanceState);
    setContentView(viewPager);

    // Action bar setup
    setupTabs(savedInstanceState);
}

private void setupTabs(Bundle savedInstanceState) {
    final ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    for (int i = 1; i <= 4; i++) {
        ActionBar.Tab tab = getSupportActionBar().newTab();
        switch (i) {
            case 1:
                tab.setText(R.string.feed).setTabListener(tabAdapter);
                tabAdapter.addTab(EventListFragment.class);
                break;
            case 2:
                tab.setText(R.string.downloads).setTabListener(tabAdapter);
                tabAdapter.addTab(LocalEventListFragment.class);
                break;
            case 3:
                tab.setText(R.string.tags).setTabListener(tabAdapter);
                tabAdapter.addTab(TagsFragment.class);
                break;
            case 4:
                tab.setText(R.string.settings).setTabListener(tabAdapter);
                tabAdapter.addTab(SettingsFragment.class);
                break;
        }
        getSupportActionBar().addTab(tab);
    }
}

TabAdapter类:

public static class TabAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {

    private final Context mContext;
    private final ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
    private final ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
    private final ActionBar mActionBar;
    private final ViewPager mViewPager;

    public TabAdapter(SherlockFragmentActivity activity, ViewPager pager){
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        mViewPager = pager;
        mViewPager.setAdapter(this);
        mViewPager.setOnPageChangeListener(this);
    }

    public void addTab(Class<?> clss){
        classes.add(clss);
        mFragments.add(Fragment.instantiate(mContext, clss.getName(),
                null));
    }

    @Override
    public Fragment getItem(int i) {
        return mFragments.get(i);
    }

    public int getId(int index){
        return mFragments.get(index).getId();
    }

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

    @Override
    public void onPageSelected(int position) {
        // fixed double call onTabReselected
        if (mActionBar.getSelectedNavigationIndex() != position)
            mActionBar.setSelectedNavigationItem(position);
    }

    @Override
    public void onPageScrollStateChanged(int i) {
    }

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

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
        final int position = tab.getPosition();
        final Fragment fragment =  mFragments.get(position);
        if (fragment != null) {
            switch (position) {
                case 0:
                    // call tab's ListFragment scroll to top item
                    ((EventListFragment) fragment).scrollToTop();
                    break;
                case 1:
                    // do something
                    break;
        }
    }
}

onTabReselected被调用,然后用户按下当前选项卡,所以我尝试进行EventListFragment滚动:

EventListFragment类:

public class EventListFragment extends SherlockListFragment {

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        mAdapter = new EventListAdapter(getSherlockActivity());
        setListAdapter(mAdapter);
    }

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

   @Override
   public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View eventListLayout = inflater.inflate(R.layout.eventlist_fragment,null);
        ListView lv = (ListView) eventListLayout.findViewById(android.R.id.list);
        ViewGroup parent = (ViewGroup) lv.getParent();
        //Remove ListView and add PullToRefreshListView in its place
        int lvIndex = parent.indexOfChild(lv);
        parent.removeViewAt(lvIndex);
        mPullToRefreshListView = onCreatePullToRefreshListView(inflater, savedInstanceState);
        parent.addView(mPullToRefreshListView, lvIndex, lv.getLayoutParams());
        return eventListLayout;
   }

   public void scrollToTop() {
      if (getSherlockActivity() != null) {  // null after screen rotation
        final ListView listView =  getListView();
        listView.post(new Runnable(){
        public void run() {
            listView.smoothScrollToPosition(0);
        }});
      }
   }

它适用于应用程序启动,但屏幕旋转后scrollToTop - getSherlockActivity()返回null
如果删除此条件检查,则会出现异常:

java.lang.IllegalStateException:尚未在 android.support.v4.app.ListFragment.getListView(ListFragment.java:222) 的 android.support.v4.app.ListFragment.ensureList(ListFragment.java:328) 创建内容视图com.project.fragment.EventListFragment.scrollToTop(EventListFragment.java:337) 在 com.project.MainActivity$TabAdapter.onTabReselected(MainActivity.java:411) 在 com.actionbarsherlock.internal.app.ActionBarWrapper$TabWrapper.onTabReselected(ActionBarWrapper.爪哇:327)

我还没有完全了解 ViewPager 及其 FragmentPagerAdapter 的工作原理。所以找不到问题,就出现了。

4

2 回答 2

1

使用这个 FragmentPageAdapter:

public class TestFragmentAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
    protected static final String[] CONTENT = new String[] { "CATEGORIAS", "PRINCIPAL", "AS MELHORES", };
    protected static final int[] ICONS = new int[] {
            R.drawable.perm_group_calendar,
            R.drawable.perm_group_camera,
            R.drawable.perm_group_device_alarms,
    };

    private int mCount = CONTENT.length;

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

    @Override
    public Fragment getItem(int position) {Fragment f = null;
    switch(position){
    case 0:
    {
    f = new ArrayListFragment();//YourFragment
    // set arguments here, if required
    Bundle args = new Bundle();
    f.setArguments(args);
    break;
    }
    case 1:
    {
        f = new HomeFragment();//YourFragment
        // set arguments here, if required
        Bundle args = new Bundle();
        f.setArguments(args);
        break;
    }
    case 2:
    {   
        f = new EndlessCustomView();//YourFragment
        // set arguments here, if required
        Bundle args = new Bundle();
        f.setArguments(args);
        break;
    }   
    default:
      throw new IllegalArgumentException("not this many fragments: " + position);
    }


    return f;
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
      return TestFragmentAdapter.CONTENT[position % CONTENT.length];
    }



    @Override
    public int getIconResId(int index) {
      return ICONS[index % ICONS.length];
    }

    public void setCount(int count) {
        if (count > 0 && count <= 10) {
            mCount = count;
            notifyDataSetChanged();
        }
    }
}

本次活动:

public class BaseSampleActivity extends SlidingFragmentActivity {
    private static final Random RANDOM = new Random();

    TestFragmentAdapter mAdapter;
    ViewPager mPager;
    PageIndicator mIndicator;
    protected ListFragment mFrag;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.themed_titles);


                getSupportActionBar().setDisplayHomeAsUpEnabled(true);

                mAdapter = new TestFragmentAdapter(getSupportFragmentManager());

                mPager = (ViewPager)findViewById(R.id.pager);
                mPager.setAdapter(mAdapter);
                mPager.setCurrentItem(1);
                mIndicator = (TitlePageIndicator)findViewById(R.id.indicator);
                mIndicator.setViewPager(mPager);


    }
于 2013-01-22T00:03:29.000 回答
0

根据这篇文章应用的解决方案:

MainActivity类:

//...
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    FragmentManager manager = getSupportFragmentManager();
    for (int i = 0; i < tabAdapter.getClasses().size(); i++) {
        String className = tabAdapter.getClasses().get(i).getName();
        if (manager.findFragmentByTag(className) != null) {
            manager.putFragment(outState, className, manager.findFragmentByTag(className));
        }
    }
}
//...

TabAdapter类:

//...
public void addTab(Class<?> clss, FragmentManager manager, Bundle savedInstanceState) {
        classes.add(clss);
        String className = clss.getName();
        tags.add(className);
        Fragment fragment;

        if (savedInstanceState != null) {
            fragment = manager.getFragment(savedInstanceState, className);
            if (fragment == null) {
                fragment = createFragment(className);
                manager.beginTransaction().add(fragment, className);
            }
        } else {
            fragment = createFragment(className);
            manager.beginTransaction().add(fragment, className);
        }
        mFragments.add(fragment);
    }
//...

其中createFragment是一个简单的方法,它通过传递的类名创建所需的片段。

于 2013-02-03T12:44:57.187 回答