刷新ViewPager Fragment中的数据

这是我的情景:

我的Activity中有ViewPager ,它包含6个片段。 我通过用手指轻扫来禁用分页,所以每当我想要滑动时我都使用相关按钮并且:

viewPager.setCurrentItem(viewPager.getCurrentItem() + 1, true); 

在每个刷过的片段中(刷卡完成后)我想向我的服务器发送一个GET请求并获取一些数据并在该片段中显示它。 这样做:

第一种方法 :我在片段中使用此代码,片段一旦可见就会运行:

 @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser) { sendGetRequest(); } } 

但是,这是一个问题: setUserVisibleHint正好在片段可见的情况下执行,因此滑动的动画带来了一些滞后(它不够平滑)。

所以我使用了Second Approach :我在托管活动中向ViewPager添加了一个OnPageChangeListener() ,如下所示:

 viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { int CurrentPossition = 0; @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { CurrentPossition = position; } @Override public void onPageScrollStateChanged(int state) { if(state == ViewPager.SCROLL_STATE_IDLE && CurrentPossition != 0){ Toast.makeText(getBaseContext(),"finished" , Toast.LENGTH_SHORT).show(); try{ new fragment_two().sendGetRequest();; }catch(Exception ex){ ex.printStackTrace(); } } } }); 

它工作得很好,并且在刷卡完成后立即显示吐司,但与完全可见的片段不同,当sendGetRequest()运行时,我得到NullPointerException。

这是StackTrace:

 04-08 20:15:37.840 12848-12848/com.example.mohamad.travelagency W/System.err: java.lang.NullPointerException 04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err: at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:152) 04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err: at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:103) 04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err: at android.app.AlertDialog.resolveDialogTheme(AlertDialog.java:143) 04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err: at android.app.AlertDialog.(AlertDialog.java:98) 04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err: at android.app.ProgressDialog.(ProgressDialog.java:77) 04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err: at com.example.mohamad.travelagency.fragment_two.GetServetData_L1(fragment_two.java:458) 04-08 20:15:37.850 12848-12848/com.example.mohamad.travelagency W/System.err: at com.example.mohamad.travelagency.MainActivity$1.onPageScrollStateChanged(MainActivity.java:124) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.support.v4.view.ViewPager.dispatchOnScrollStateChanged(ViewPager.java:1811) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.support.v4.view.ViewPager.setScrollState(ViewPager.java:404) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.support.v4.view.ViewPager.access$000(ViewPager.java:91) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.support.v4.view.ViewPager$3.run(ViewPager.java:250) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.view.Choreographer.doCallbacks(Choreographer.java:574) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.view.Choreographer.doFrame(Choreographer.java:543) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.os.Handler.handleCallback(Handler.java:733) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95) 04-08 20:15:37.860 12848-12848/com.example.mohamad.travelagency W/System.err: at android.os.Looper.loop(Looper.java:136) 04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5271) 04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err: at java.lang.reflect.Method.invokeNative(Native Method) 04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err: at java.lang.reflect.Method.invoke(Method.java:515) 04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:851) 04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:667) 04-08 20:15:37.870 12848-12848/com.example.mohamad.travelagency W/System.err: at dalvik.system.NativeStart.main(Native Method) 

任何想法都会很棒。 最好的祝福

答案 :Daniel Nugent的代码运行良好,除了在发送GET请求时显示ProgressDialog我用过:

 final ProgressDialog dialog = new ProgressDialog(new MainActivity()); 

这段代码也返回了NullPointerException,我删除了它,现在运行良好。

使用ViewPager.OnPageChangeListener是正确的方法,但您需要稍微重构一下适配器,以便保留对FragmentPagerAdapter中包含的每个Fragment的引用。

您可以使用适配器中的instantiateItem()方法覆盖来执行此操作,这是一个简化示例:

  class PagerAdapter extends FragmentPagerAdapter { String tabTitles[] = new String[] { "One", "Two", "Three", "Four"}; Context context; //This will contain your Fragment references: public Fragment[] fragments = new Fragment[tabTitles.length]; public PagerAdapter(FragmentManager fm, Context context) { super(fm); this.context = context; } @Override public int getCount() { return tabTitles.length; } @Override public Fragment getItem(int position) { switch (position) { case 0: return new FragmentOne(); case 1: return new FragmentTwo(); case 2: return new FragmentThree(); case 3: return new FragmentFour(); } return null; } //This populates your Fragment reference array: @Override public Object instantiateItem(ViewGroup container, int position) { Fragment createdFragment = (Fragment) super.instantiateItem(container, position); fragments[position] = createdFragment; return createdFragment; } @Override public CharSequence getPageTitle(int position) { // Generate title based on item position return tabTitles[position]; } } 

然后,使用适配器中包含的片段,而不是创建新的片段:

 mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { // do this instead, assuming your adapter reference // is named mAdapter: Fragment frag = mAdapter.fragments[position]; if (frag != null && frag instanceof FragmentTwo) { ((FragmentTwo)frag).sendGetRequest(); } } @Override public void onPageScrollStateChanged(int state) { } }); 

请注意,如果在适配器中使用不同的Fragment类,则可以实现定义sendGetRequest()的接口,并在每个Fragment类中实现sendGetRequest()方法。

如果不使用接口方法,则需要将Fragment转换为您自己的Fragment类型,如上例所示,即:

 if (frag instanceof FragmentTwo) { ((FragmentTwo)frag).sendGetRequest(); } 

而不是在视图寻呼机侦听器中调用sendGetRequest()方法,而是在fragment_two片段类中的onCreateView方法中调用GET请求。 这样做的原因是您确保fragment_two中的所有视图都已通过片段的生命周期事件正确初始化。