ViewPager 的 SetCurrentItem 仅在 OnTabSelected 中不起作用

SetCurrentItem for ViewPager is not working in OnTabSelected only

一个小问题找了好久也没搞清楚。如果能帮我解决问题,那就太好了。 我有一个 ActionbarActivity,我实际上想要四个选项卡,所以我只使用了 viewpager 和 actionbar 选项卡。一切正常但是当我使用 viewPager.setCurrentItem() 在我的 OnTabSelected() 方法中,它给出空点异常,即使它在 OnTabReselect() 或 onTabUnselect() 中工作正常 这是我的主要代码 activity 包裹 co.howlabs.cafe.lahore;

import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;

public class MainActivity extends ActionBarActivity implements TabListener {
    ViewPager viewpager;
    TabPagerAdapter TabAdapter;
    ActionBar actionbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // actionBar.setDisplayShowTitleEnabled(false);
       // actionBar.setDisplayShowHomeEnabled(false);
        setContentView(R.layout.activity_main);
        actionbar = getSupportActionBar();
        actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        ActionBar.Tab tab1 = actionbar.newTab();
        tab1.setText("Promotions");
        tab1.setTabListener(this);

        ActionBar.Tab tab2 = actionbar.newTab();
        tab2.setText("All Cafes");
        tab2.setTabListener(this);

        ActionBar.Tab tab3 = actionbar.newTab();
        tab3.setText("Categories");
        tab3.setTabListener(this);

        ActionBar.Tab tab4 = actionbar.newTab();
        tab4.setText("Recommended");
        tab4.setTabListener(this);

        actionbar.addTab(tab1);
        actionbar.addTab(tab2);
        actionbar.addTab(tab3);
        actionbar.addTab(tab4);

        viewpager = (ViewPager)findViewById(R.id.pager);
        FragmentManager fragmentmanager = getSupportFragmentManager();
        viewpager.setAdapter(new TabPagerAdapter(fragmentmanager));
        viewpager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {
                actionbar.setSelectedNavigationItem(arg0);

            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub

            }
        });
    }

    @Override
    public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
        viewpager.setCurrentItem(arg0.getPosition());   //here throws error
        Log.d("tab", String.valueOf(arg0.getPosition())); //gives the correct position if comments the above line
    }

    @Override
    public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {

    }

    @Override
    public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
        viewpager.setCurrentItem(arg0.getPosition()); //works fine here
    }
}

这是 class 用于 tabpager 适配器

package co.howlabs.cafe.lahore;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

public class TabPagerAdapter extends FragmentStatePagerAdapter {

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

          @Override
          public Fragment getItem(int i) {
            switch (i) {
                case 0:
                    return new Promotions();
                case 1:
                    return new AllCafes();
                case 2:
                    return new Categories();
                case 3:
                    return new Recommended();
                }
            return null;
          }

          @Override
          public int getCount() {
            return 4; //No of Tabs
          }

}

这是我的LogCat错误信息

04-11 15:16:40.624: E/AndroidRuntime(1841): FATAL EXCEPTION: main
04-11 15:16:40.624: E/AndroidRuntime(1841): java.lang.RuntimeException: Unable to start activity ComponentInfo{co.howlabs.cafe.lahore/co.howlabs.cafe.lahore.MainActivity}: java.lang.NullPointerException
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.ActivityThread.access0(ActivityThread.java:130)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.os.Looper.loop(Looper.java:137)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.ActivityThread.main(ActivityThread.java:4745)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at java.lang.reflect.Method.invokeNative(Native Method)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at java.lang.reflect.Method.invoke(Method.java:511)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at dalvik.system.NativeStart.main(Native Method)
04-11 15:16:40.624: E/AndroidRuntime(1841): Caused by: java.lang.NullPointerException
04-11 15:16:40.624: E/AndroidRuntime(1841):     at co.howlabs.cafe.lahore.MainActivity.onTabSelected(MainActivity.java:75)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.support.v7.app.ActionBarImplICS$TabWrapper.onTabSelected(ActionBarImplICS.java:558)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at com.android.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:570)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at com.android.internal.app.ActionBarImpl.addTab(ActionBarImpl.java:499)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at com.android.internal.app.ActionBarImpl.addTab(ActionBarImpl.java:485)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.support.v7.app.ActionBarImplICS.addTab(ActionBarImplICS.java:247)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.support.v7.app.ActionBarImplJB.addTab(ActionBarImplJB.java:20)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at co.howlabs.cafe.lahore.MainActivity.onCreate(MainActivity.java:43)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.Activity.performCreate(Activity.java:5008)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
04-11 15:16:40.624: E/AndroidRuntime(1841):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
04-11 15:16:40.624: E/AndroidRuntime(1841):     ... 11 more

如堆栈跟踪所示,调用 actionbar.addTab(...).

后触发了 onTabSelected()

知道了这一点,就应该清楚为什么 viewpager.setCurrentItem() 会抛出 NPE。添加第一个选项卡时,该字段尚未初始化,只是因为当前您在 viewpager = (ViewPager)findViewById(R.id.pager) 设置选项卡后

解决方案是将 viewpager = (ViewPager)findViewById(R.id.pager) 移动到某个地方 第一次 addTab() 调用之前(当然仍然在 setContentView(R.layout.activity_main) 之后)。