我有一个父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 的工作原理。所以找不到问题,就出现了。