onPageSelected不适用于第一页
我的寻呼机适配器(扩展PagerAdepter)中有一个textview。我用MainActivity的onPageSelected更新这个textview。其位置> 0的更新文本视图,但起始页面(位置0)不会在启动时更新。当我向前滑动然后向后滑动;它设置位置0的值,但我不能将值设置为ON START。如何设置星级页面的值?onPageSelected不适用于第一页
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;
}
}
});
}
}
您可以手动调用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());
}
});
编辑
现在它将会不克等Null Pointer exception
通过如指出@ metemet06
我该如何使用它?我找不到 – metemet06 2013-04-18 04:17:43
紧跟在你的'viewPager.setAdapter(pagerAdapter)'后面,调用'pagerAdapter.onPageSelected(0)' – ianhanniballake 2013-04-18 04:43:17
那么我会在pagerAdapter中创建onPageSelected()方法吗? – metemet06 2013-04-18 04:47:20
在我看来,你真的想要做什么是压倒一切的getPageTitle()
,然后在其他地方,抓住该网页标题并将其设置为一个TextView的文本。
通过这种方式初始化您的活动,初始化PagerAdapter并致电getTitle(0)
。这会让你获得页面0的标题。现在在活动的textview中设置它。稍后,只要您更改页面,只需拨打getTitle(newPosition)
并更新该TextView即可。
您可能使用一些AsyncTasks来加载数据集,并且很难确定哪个任务是最后一个任务完成的。只有在完成最后一项任务后,当整个数据集完成时,您才可以调用OnPageSelected,因为它在整个数据集上对UI执行刷新。
而不是在第一次加载页面时手动调用OnPageSelected函数,而是逐步建立“正常”UI。稍后,当用户更改页面时,数据集应该是完整的,并且保存在OnPageSelected函数中进行更新。
因为我做了什么,在这里建议,并没有工作,我将发布什么做的工作对我来说是将实体化功能onPageScrolled,像这样:
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
adapter.closeText(arg0, viewPager);
}
也许它的工作的原因是onPagesScrolled会在android任务管理器的下方被激活,所以我们可以防止页面被夸大的不需要的情况,并跳过视图的侦听器附件。
我通过在我的活动的onCreate()方法中添加应为第一页执行的代码来修复了我的应用程序中的问题。
它不是最漂亮的黑客,并涉及一些冗余的代码,但因为我只想在页面更改时加载一些文本数据,所以对我来说这是最简单的方法。
调用onPageSelected()手动导致NullPointerExceptions,只是das在上面的其他注释中描述。
我的解决方案是扩展寻呼机适配器,并在其中创建一个接口。然后让适配器在创建适配器后只调用一次接口。在界面回调里,你可以调用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;
}
}
这是一个不错的主意,在我的情况下完美!我想花更多的时间来研究在片段连接到活动之后是否实际调用了finishUpdate。 – Entreco 2016-05-25 07:30:04
谢谢:)根据谷歌[FragmentPagerAdapter.finishUpdate](https://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html#finishUpdate(android.view.ViewGroup))被称为当所示页面的更改已完成。所以,每当片段发生变化时,都会调用完成更新。此外,如果我们深入了解源代码,我们可以看到这种方法提交并执行所有未完成的交易:) – 2016-05-25 07:39:45
它值得更多upvotes – deviant 2017-10-06 15:52:15
此代码适用于我。首先初始化pagechange侦听器。 setCurrentItem之后。
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(1);
final ViewPager.OnPageChangeListener listener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
viewPager.addOnPageChangeListener(listener);
viewPager.setCurrentItem(position);
工作对我来说下一个代码
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) {
}
};
这是一个很好的技巧,可以轻松解决问题。 – GregM 2017-03-02 16:02:39
其实我找到了一个很好的方法基于这个answer。
问题是当设置侦听器时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);
}
}
}
}
为什么你PageAdapter有它的风景吗?这听起来很腥。你想达到什么目的? – dmon 2013-04-18 03:52:50
我从数据库中获取数据并将其设置为paderadapters textview – metemet06 2013-04-18 03:58:35