Android onPageSelected不';我不在第一页工作
我的寻呼机适配器(extends PagerAdepter)中有一个文本视图。我用MainActivity的onPageSelected更新这个文本视图。其位置>0的更新文本视图,但起始页(位置0)不会在启动时更新。当我向前滑动,然后向后滑动;它为位置0设置值,但我无法在开始时设置值。如何设置星页的值Android onPageSelected不';我不在第一页工作,android,android-viewpager,Android,Android Viewpager,我的寻呼机适配器(extends PagerAdepter)中有一个文本视图。我用MainActivity的onPageSelected更新这个文本视图。其位置>0的更新文本视图,但起始页(位置0)不会在启动时更新。当我向前滑动,然后向后滑动;它为位置0设置值,但我无法在开始时设置值。如何设置星页的值 public void onPageSelected(int position) { switch (position) { case
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;
}
}
});
}
}
创建
OnPageChangeListener
时,可以手动调用onPageSelected(0)
,以设置启动状态:
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());
}
});
编辑
现在它将不会得到
空指针异常
,正如@metemet06所指出的,在我看来,您真正想要做的是覆盖,然后,在其他地方,抓取该页面标题并将其设置为TextView的文本
这样,在初始化活动时,初始化PagerAdapter并调用
getTitle(0)
。这将为您获取第0页的标题。现在在活动的文本视图中设置它。以后,每当您更改页面时,只需调用getTitle(newPosition)
并更新该文本视图。您可能会使用一些异步任务来加载数据集,并且很难确定哪个任务将最后完成。只有在完成最后一个任务之后,当整个数据集完成时,您才能调用OnPageSelected,因为它正在对整个数据集的UI进行刷新
第一次加载页面时,不要手动调用OnPageSelected函数,而是以“正常”的方式逐步构建UI。稍后,当用户更改页面时,数据集应该是完整的,并将其保存,以便在OnPageSelected函数中进行更新。因为我做了此处建议的事情,但它不起作用,所以我将发布对我起作用的是将实例化函数添加到onPageScrolled,如下所示:
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
adapter.closeText(arg0, viewPager);
}
可能它起作用的原因是OnPagesScrold在android任务管理器的下一行被激活,因此我们防止了不必要的情况,即页面通过跳过视图的侦听器附件而膨胀。我通过在onCreate()中添加应为第一页执行的代码,在我的应用程序中修复了这个问题-我的活动方法 这不是最漂亮的黑客攻击,涉及一些冗余代码,但因为我只想在页面更改时加载一些文本数据,所以在我的情况下,这是最简单的方法
手动调用onPageSelected()会导致NullPointerException,正如上面其他注释中所述。我的解决方案是扩展寻呼机适配器并在其中创建一个接口。然后使适配器在创建适配器后仅调用接口一次。在接口回调内部,您可以调用onPageChanged方法,而不必使用nullpointerexception。将此类添加到项目中并从中扩展适配器。在将适配器设置为viewpager之前,不要忘记将listener设置为adapter。下面是适配器类:
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;
}
}
对我来说,下一个代码是什么
viewPager.addOnPageChangeListener(myOnPageChangeListener);
事实上,我找到了一个很好的方法 问题是设置侦听器时,
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
方法只调用一次,非常适合处理第一页的情况。我的解决方案是扩展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);
}
}
}
}
类MyViewPager扩展了ViewPager{
private List_Listeners=new ArrayList();
公共MyViewPager(上下文){
超级(上下文);
}
公共MyViewPager(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
public void addOnPageChangeListener(OnPageChangeListener侦听器){
super.addOnPageChangeListener(listener);
_添加(侦听器);
}
@凌驾
public void removeOnPageChangeListener(OnPageChangeListener侦听器){
super.removeOnPageChangeListener(监听器);
_删除(侦听器);
}
@凌驾
公共无效setCurrentItem(最终整数项){
如果(item!=getCurrentItem()){
super.setCurrentItem(项目);
}否则{
post(新的Runnable(){
@凌驾
公开募捐{
dispatchOnPageSelected(项目);
}
});
}
}
已选择private void dispatchOnPageSelected(内部位置){
for(int i=0,size=_Listeners.size();i
为什么页面适配器中有视图?这听起来很可疑。你们想实现什么?我从数据库中获取数据并将其设置为paderadapters TextView我如何使用它?在您的viewPager.setAdapter(pagerAdapter)
之后,我想不出是什么原因,请致电pagerAdapter.onPageSelected(0)
谢谢您的帮助。但它仍然给了我nullpointerexception。我认为即使我们在设置适配器后使用它,pageradapter中的textview仍然没有准备好!这是不正确的,如果您手动调用onPageSelected,则寻呼机/适配器可能尚未准备就绪,并且正如metemet06所指出的,您将得到一个空指针异常。@Soham完全正确。片段尚未附加到其父级,如果您的代码依赖于所附加的片段(getParentFragment()或getActivity()),它将崩溃。还有人有什么想法吗?这是个好主意
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);
}
}
}
}
@Override
public void addOnPageChangeListener(@NonNull OnPageChangeListener listener) {
super.addOnPageChangeListener(listener);
if (getAdapter() != null && getAdapter().getCount() > 0) {
post(() -> listener.onPageSelected(getCurrentItem()));
}
}