59

我的寻呼机适配器(扩展 PagerAdepter)中有一个 textview。我用 MainActivity 的 onPageSelected 更新了这个文本视图。其位置 > 0 的更新文本视图,但启动页面(位置 0)不会在启动时更新。当我向前滑动然后向后滑动;它为位置 0 设置值,但我无法在开始时设置值。如何设置明星页面的价值?

public void onPageSelected(int position) {

             switch (position) {
                case 0: 

                     PagerAdapter.tv.setText("value"); // => doesnt work on start

                    break;

                            default:
                                   PagerAdapter.tv.setText("value");
                                         break;
}
}

完整代码:

public class QuizStart extends SlidingFragmentActivity {
 @Override
        protected void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

           this.setContentView(R.layout.activity_main);

              mPager = (ViewPager)findViewById(R.id.pager);         
            QuestionPagerAdapter mAdapter = new QuestionPagerAdapter();

            mPager.setAdapter(mAdapter);
            QuizStart.onPageSelected(0);

         mPager.setOnPageChangeListener(new OnPageChangeListener() {


            @Override
            public void onPageScrollStateChanged(int arg0) { }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) { }

            @Override
            public void onPageSelected(int position) {

             switch (position) {
                case 0: 

                     PagerAdapter.tv.setText("value"); // => doesnt work on start

                    break;

                            default:
                                   PagerAdapter.tv.setText("value");
                                         break;
                }
            }

        });
}
}
4

10 回答 10

79

onPageSelected(0)您可以在创建时手动调用OnPageChangeListener以设置起始状态:

OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
    @Override
    public void onPageScrollStateChanged(int arg0) { }

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) { }

    @Override
    public void onPageSelected(int position) {

        switch (position) {
        case 0: 
            QuizStart.next.setText(getmycurrentpage()+"");
            break;

        default:

            QuizStart.next.setText(getmycurrentpage()+"");
            break;
        }
    }
});

   mPager.setOnPageChangeListener(pageChangeListener);
   // do this in a runnable to make sure the viewPager's views are already instantiated before triggering the onPageSelected call
   mPager.post(new Runnable()
   {
       @Override
       public void run() 
       {
           pageChangeListener .onPageSelected(viewPager.getCurrentItem());
       }
   });

编辑

现在它不会像@metemet06Null Pointer exception所指出的那样

于 2013-04-18T03:50:18.320 回答
54

对我来说下一个代码

    viewPager.addOnPageChangeListener(myOnPageChangeListener);

.

    ViewPager.OnPageChangeListener myOnPageChangeListener = new ViewPager.OnPageChangeListener() {

    //declare key
    Boolean first = true;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (first && positionOffset == 0 && positionOffsetPixels == 0){
            onPageSelected(0);
            first = false;
        }
    }

    @Override
    public void onPageSelected(int position) {
        //do what need
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
};
于 2016-01-08T11:13:23.610 回答
4

我的解决方案是扩展寻呼机适配器并在其中创建一个接口。然后让适配器在创建适配器后只调用一次接口。在接口回调中,您可以调用 onPageChanged 方法而不会出现 nullpointerexception。将此类添加到您的项目中并从中扩展您的适配器。在将适配器设置为 viewpager 之前,不要忘记将侦听器设置为适配器。适配器类如下:

public abstract class ExtendedPagerAdapter extends FragmentPagerAdapter {

private boolean instantiated;
private AdapterListener adapterListener;

public interface AdapterListener {
    void onAdapterInstantiated();
}

public ExtendedPagerAdapter(FragmentManager fragmentManager) {
    this(fragmentManager, null);
}

public ExtendedPagerAdapter(FragmentManager fragmentManager, AdapterListener adapterListener) {
    super(fragmentManager);
    this.adapterListener = adapterListener;
    instantiated = false;
}

@Override
public void finishUpdate(ViewGroup container) {
    super.finishUpdate(container);
    if (!instantiated) {
        instantiated = true;
        if (adapterListener != null) {
            adapterListener.onAdapterInstantiated();
        }
    }
}

public void setAdapterInstantiatedListener(AdapterListener adapterListener) {
    this.adapterListener = adapterListener;
}
}
于 2015-09-25T08:16:51.480 回答
1

我通过在我的活动的 onCreate() 方法中添加应该为第一页执行的代码来解决我的应用程序中的问题。

它不是最漂亮的 hack 并且涉及一些冗余代码,但由于我只想在页面更改时加载一些文本数据,所以在我的情况下这是最简单的方法。

手动调用 onPageSelected() 会导致 NullPointerExceptions,正如上面其他评论中所述。

于 2015-09-11T12:31:57.870 回答
0

您可能使用一些 AsyncTask 来加载数据集,并且很难确定哪个任务将是最后完成的。只有在最后一个任务完成后,当整个数据集完成时,您才能调用 OnPageSelected,因为它正在 UI 上对整个数据集进行刷新。

与其在第一次加载页面时手动调用 OnPageSelected 函数,不如以“正常”方式逐步构建 UI。稍后,当用户更改页面时,数据集应该是完整的并保存,以便在 OnPageSelected 函数中进行更新。

于 2015-04-20T15:03:47.807 回答
0

在我看来,您真正想要做的是覆盖getPageTitle(),然后在其他地方获取该页面标题并将其设置为 TextView 的文本。

这样,当您初始化活动时,初始化 PagerAdapter 并调用getTitle(0). 这将为您提供第 0 页的标题。现在在 Activity 的文本视图中设置它。稍后,每当您更改页面时,只需调用getTitle(newPosition)并更新该 TextView。

于 2013-04-18T04:03:05.303 回答
0

我的解决方案是扩展 ViewPager

class MyViewPager extends ViewPager {

    private List<OnPageChangeListener> _Listeners = new ArrayList<>();

    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void addOnPageChangeListener(OnPageChangeListener listener) {
        super.addOnPageChangeListener(listener);
        _Listeners.add(listener);
    }

    @Override
    public void removeOnPageChangeListener(OnPageChangeListener listener) {
        super.removeOnPageChangeListener(listener);
        _Listeners.remove(listener);
    }

    @Override
    public void setCurrentItem(final int item) {
        if (item != getCurrentItem()) {
            super.setCurrentItem(item);
        } else {
            post(new Runnable() {
                @Override
                public void run() {
                    dispatchOnPageSelected(item);
                }
            });
        }
    }

    private void dispatchOnPageSelected(int position) {
        for (int i = 0, size = _Listeners.size(); i < size; i++) {
            OnPageChangeListener listener = _Listeners.get(i);
            if (listener != null) {
                listener.onPageSelected(position);
            }
        }
    }
}
于 2016-10-22T17:37:10.673 回答
0

因为我做了这里的建议但没有用,我将发布对我有用的方法是将实例化函数添加到 onPageScrolled,如下所示:

   @Override
   public void onPageScrolled(int arg0, float arg1, int arg2) {

           adapter.closeText(arg0, viewPager);

    }

可能它起作用的原因是 onPagesScrolled 在 android 任务管理器的行下方被激活,因此我们通过跳过侦听器附件到视图来防止页面膨胀的不需要的情况。

于 2015-07-08T07:41:12.873 回答
0
@Override
public void addOnPageChangeListener(@NonNull OnPageChangeListener listener) {
    super.addOnPageChangeListener(listener);
    if (getAdapter() != null && getAdapter().getCount() > 0) {
        post(() -> listener.onPageSelected(getCurrentItem()));
    }
}
于 2018-12-14T08:30:10.743 回答
0

其实我找到了一个基于这个答案的好方法。

问题是在ViewPager设置监听器时没有完全加载,第一页被调用但里面的片段ViewPager还没有完全初始化。

为了解决这个问题,我只保留一个变量来知道第一页是否被调用:

private boolean mFirstPageCalled = false;

然后在监听器中:

@Override
public void onPageSelected(int position) {

    if(mFirstPageCalled) {
        // Do your thing
    } else {
        mFirstPageCalled = true;
    }
}

最后要做的是处理丢失的第一页,这可以在ViewPager完全创建后完成:

    mViewPager.post(new Runnable(){
        @Override
        public void run() {
            // Do your thing
        }
    });

就我而言,我只是在这里调用当前显示的片段并对其进行处理:

Fragment currentFragment = mPagerAdapter.instantiateItem(mViewPager, mViewPager.getCurrentItem());
currentFragment.customAction();

post方法只调用一次,非常适合处理第一页的情况。

于 2016-05-13T10:18:55.557 回答