奇怪的问题刷新ViewPager与新的内容:

我从Web服务接收数据,这个数据被parsing成Application类中的一个对象,这个对象在我的例子中是一个Report类,它包含了一个应该填充ViewPagerTabs列表。 所以这个报告存储在Application类的currentReport参数中。

每个选项卡应该是ViewPager一个页面。 因此,当我第一次接收数据并parsing数据时,所有工作都完美无缺,并且查看传呼机中填充了正确的数据并显示出来。

当我想从服务器获取一个新的Report ,并使用parsing到currentReport参数的新数据刷新ViewPager时,我的问题就开始了。

我的ViewPager是可滑动的,并具有制表符导航,所以当我尝试重新实例化与新ReportViewPager ,我看到正确数量的选项卡添加到tabHost 。 由于某种原因,新报告的片段与前一个片段重叠。 因此,如果新报告中的标签数量大于之前报告中的标签数量,那么除了部分新报告之外,我还可以看到之前报告中的标签(例如,如果第一份报告中有一个标签,在新的我有3,然后我看到从前一个和最后两个来自下一个片段)。

我已经开始从这个教程的发展,并添加smoe代码: http ://thepseudocoder.wordpress.com/2011/10/13/android-tabs-viewpager-swipe-able-tabs-ftw/

这是我的标签活动代码:

 public class TabsViewPagerFragmentActivity extends FragmentActivity implements ViewPager.OnPageChangeListener, TabHost.OnTabChangeListener { static final String TAG = TabsViewPagerFragmentActivity.class.getSimpleName(); private TabHost mTabHost; private ViewPager mViewPager; private HashMap<String, TabInfo> mapTabInfo; public ViewPagerAdapter mPagerAdapter; private TextView tvReportName, tvTabTitle; private Button bBackToParameters; private Dialog progressDialog; private SGRaportManagerAppObj application; private int numberOfTabs = 0; private Display display; public static final int POPUP_MARGIN = 6; LeftSideMenu leftSideMenu; public void NotifyTabActivityViewPagerAdapter() { mPagerAdapter.notifyDataSetChanged(); } public ViewPagerAdapter getTabActivityViewPagerAdapter() { return mPagerAdapter; } public ViewPager getTabActivityViewPager() { return mViewPager; } public void setCurrentTabTitle (String title) { tvTabTitle.setText(title); Log.d(TAG, "set tab title from activity: "+title); } /** * Maintains extrinsic info of a tab's construct */ private class TabInfo { private String tag; private Class<?> clss; private Bundle args; private Fragment fragment; TabInfo(String tag, Class<?> clazz, Bundle args) { this.tag = tag; this.clss = clazz; this.args = args; } } /** * A simple factory that returns dummy views to the Tabhost */ class TabFactory implements TabContentFactory { private final Context mContext; /** * @param context */ public TabFactory(Context context) { mContext = context; } /** (non-Javadoc) * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String) */ public View createTabContent(String tag) { View v = new View(mContext); v.setMinimumWidth(0); v.setMinimumHeight(0); return v; } } /** (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle) */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); application = SGRaportManagerAppObj.getInstance(); display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); // Inflate the layout setContentView(R.layout.tabs_screen_activity_layout); tvTabTitle = (TextView) findViewById(R.id.tvTabName); tvReportName = (TextView)findViewById(R.id.tvReportName); tvReportName.setText(application.currentReport.getName()+ " - "); bBackToParameters = (Button) findViewById(R.id.bBackToParameters); leftSideMenu = (LeftSideMenu) findViewById(R.id.leftSideMenu); applyOnClickListenerToLeftSideMenu(); findViewById(R.id.showLeftMenuButton).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); int width = d.getWidth(); View panel = findViewById(R.id.leftSideMenu); View appPanel = findViewById(R.id.appLayout); if (panel.getVisibility() == View.GONE){ appPanel.setLayoutParams(new LinearLayout.LayoutParams(width, LayoutParams.FILL_PARENT)); panel.setVisibility(View.VISIBLE); applyOnClickListenerToLeftSideMenu(); }else{ ToggleButton button = (ToggleButton) findViewById(R.id.showLeftMenuButton); button.setChecked(false); panel.setVisibility(View.GONE); } } }); // Initialise the TabHost progressDialog = DialogUtils.createProgressDialog(this, this.getString(R.string.populating_view_pager)); progressDialog.show(); if (SGRaportManagerAppObj.getInstance().parametersRepository.getParametersRepository().size() == 0) { bBackToParameters.setText(R.string.back_to_report_list); } this.initialiseTabHost(savedInstanceState); if (savedInstanceState != null) { mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state } // Intialise ViewPager this.intialiseViewPager(); progressDialog.dismiss(); } /** (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle) */ protected void onSaveInstanceState(Bundle outState) { outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected super.onSaveInstanceState(outState); } /** * Initialise ViewPager */ public void intialiseViewPager() { List<Fragment> fragments = new Vector<Fragment>(); // TabInfo tabInfo = null; if (application.getCurrentDataSource().equals(DataSource.SSRS)) { numberOfTabs = application.currentReport.getTabsList().size(); } else if (application.getCurrentDataSource().equals(DataSource.SGRDL)) { numberOfTabs = application.currentReport.getODTabsList().size(); Log.d(TAG, "CURRENT REPORT FROM VIEW PAGER: "+ application.currentReport.toString()); } Log.d(TAG,"Current Tabs number from TabsViewPager activity: " +numberOfTabs); if (application.getCurrentDataSource().equals(DataSource.SSRS)) { for (int i = 0; i < numberOfTabs; i++) { Tab tempTab = application.currentReport.getTabsList().get(i); if (tempTab.getTabTemplateId() == 7) { GridFragment gridFragment = new GridFragment(tempTab); fragments.add(gridFragment); } else if (tempTab.getTabTemplateId() == 8) { NewChartFragment chartFragment = new NewChartFragment(tempTab, this); fragments.add(chartFragment); } } } else if (application.getCurrentDataSource().equals(DataSource.SGRDL)) { for (int i = 0; i < numberOfTabs; i++) { ODTab tempTab = application.currentReport.getODTabsList().get(i); if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT)) { GridFragment gridFragment = GridFragment.newInstance(tempTab.getTabId()); fragments.add(gridFragment); } else if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT)) { NewChartFragment chartFragment = NewChartFragment.newInstance(tempTab.getTabId()); fragments.add(chartFragment); } } } Log.d(TAG, "Current report fragments set to adapter: "+fragments.toString()); /* if (this.mPagerAdapter == null) { this.mPagerAdapter = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments); } else { this.mPagerAdapter.removeAllFragments(); this.mPagerAdapter.addFragmentsListToAdapter(fragments); } */ this.mPagerAdapter = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments); this.mViewPager = (ViewPager)super.findViewById(R.id.pager); // this.mViewPager.setAdapter(null); this.mViewPager.setAdapter(this.mPagerAdapter); this.mViewPager.setOffscreenPageLimit(0); this.mViewPager.setOnPageChangeListener(this); Log.d(TAG, "Adapter initialized!"); } /** * Initialise the Tab Host */ public void initialiseTabHost(Bundle args) { mTabHost = (TabHost)findViewById(android.R.id.tabhost); /* //new edit if (mTabHost.getChildCount() > 0) { mTabHost.removeAllViews(); } */ mTabHost.setup(); TabInfo tabInfo = null; mapTabInfo = new HashMap<String, TabsViewPagerFragmentActivity.TabInfo>(); if (args != null) {} else { if (application.getCurrentDataSource().equals(DataSource.SSRS)) { int numberOfTabs = application.currentReport.getTabsList().size(); for (int i = 0; i < numberOfTabs; i++) { Tab tempTab = application.currentReport.getTabsList().get(i); if (tempTab.getTabTemplateId() == 7) { //GridFragment gridFragment = new GridFragment(tempTab); TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), GridFragment.class, args))); this.mapTabInfo.put(tabInfo.tag, tabInfo); } else if (tempTab.getTabTemplateId() == 8) { TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), NewChartFragment.class, args))); this.mapTabInfo.put(tabInfo.tag, tabInfo); } } } else if (application.getCurrentDataSource().equals(DataSource.SGRDL)) { int numberOfTabs = application.currentReport.getODTabsList().size(); for (int i = 0; i < numberOfTabs; i++) { ODTab tempTab = application.currentReport.getODTabsList().get(i); // Log.d(TAG,"Crashed Tab type: "+ tempTab.getTabType()); if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT)) { //GridFragment gridFragment = new GridFragment(tempTab); TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), GridFragment.class, args))); this.mapTabInfo.put(tabInfo.tag, tabInfo); } else if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT)) { TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), NewChartFragment.class, args))); this.mapTabInfo.put(tabInfo.tag, tabInfo); } } } } // Default to first tab //this.onTabChanged("Tab1"); // mTabHost.setOnTabChangedListener(this); } /** * Add Tab content to the Tabhost * @param activity * @param tabHost * @param tabSpec * @param clss * @param args */ private static void AddTab(TabsViewPagerFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) { // Attach a Tab view factory to the spec ImageView indicator = new ImageView(activity.getBaseContext()); indicator.setPadding(10, 10, 10, 10); indicator.setImageResource(R.drawable.tab_select_icon_selector); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(10, 10, 10, 10); indicator.setLayoutParams(lp); tabSpec.setIndicator(indicator); tabSpec.setContent(activity.new TabFactory(activity)); tabHost.addTab(tabSpec); } /** (non-Javadoc) * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String) */ public void onTabChanged(String tag) { //TabInfo newTab = this.mapTabInfo.get(tag); int pos = this.mTabHost.getCurrentTab(); this.mViewPager.setCurrentItem(pos); } /* (non-Javadoc) * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int) */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // TODO Auto-generated method stub } /* (non-Javadoc) * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int) */ @Override public void onPageSelected(int position) { // TODO Auto-generated method stub this.mTabHost.setCurrentTab(position); } /* (non-Javadoc) * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int) */ @Override public void onPageScrollStateChanged(int state) { // TODO Auto-generated method stub } 

这是我的适配器代码:

 public class ViewPagerAdapter extends FragmentPagerAdapter { private List<Fragment> fragments; /** * @param fm * @param fragments */ public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) { super(fm); this.fragments = fragments; } /* (non-Javadoc) * @see android.support.v4.app.FragmentPagerAdapter#getItem(int) */ @Override public Fragment getItem(int position) { return this.fragments.get(position); } /* (non-Javadoc) * @see android.support.v4.view.PagerAdapter#getCount() */ @Override public int getCount() { return this.fragments.size(); } @Override public int getItemPosition(Object object) { return POSITION_NONE; } 

我的AsyncTaskparsing数据并更新ViewPager:

 public class ParseSGRDLReportDataAsyncTask extends AsyncTask<String, Object, Report>{ static final String TAG = ParseSGRDLReportDataAsyncTask.class.getSimpleName(); private Activity activity; private Exception exception; private ResponseHandler responseHandler = new ResponseHandler(); private SGRaportManagerAppObj application; private Dialog progressDialog; public ParseSGRDLReportDataAsyncTask(LoginScrActivity activity) { super(); this.activity = activity; } public ParseSGRDLReportDataAsyncTask(Activity currentActivity) { super(); this.activity = currentActivity; } public void onPreExecute() { application = SGRaportManagerAppObj.getInstance(); progressDialog = DialogUtils.createProgressDialog(activity, activity.getString(R.string.parse_data_dialog_message)); progressDialog.show(); } @Override protected Report doInBackground(String... params) { String ReportDataString = params[0]; try{ return DataAccessManager.parseSGRDLReportData(ReportDataString); } catch (Exception e) { exception = e; return null; } } @Override public void onPostExecute(Report result) { progressDialog.dismiss(); if (exception == null) { if (activity.getClass() == TabsViewPagerFragmentActivity.class) { application.currentReport = result; Log.d(TAG, "Current report parsed is: "+result); ((TabsViewPagerFragmentActivity)activity).intialiseViewPager(); ((TabsViewPagerFragmentActivity)activity).initialiseTabHost(null); ((TabsViewPagerFragmentActivity)activity).NotifyTabActivityViewPagerAdapter(); } else { responseHandler.handleProcessSGRDLReportDataResult(result, activity); } } else { processException(); } } private void processException() { Toast.makeText(activity, activity.getString(R.string.error_when_parsing_data), 3000).show(); } } 

回答:对于所有在同一个问题上遇到的人都提供了@Luksprogbuild议,这是对我来说最终的结果,在AsyncTask中我需要添加这个:

 if (activity.getClass() == TabsViewPagerFragmentActivity.class) { TabsViewPagerFragmentActivity tempActivity = ((TabsViewPagerFragmentActivity)activity); application.currentReport = result; Log.d(TAG, "Current report parsed is: "+result); List<Fragment> frags = tempActivity.getTabActivityViewPagerAdapter().getFragments(); // getter method in your adapter FragmentTransaction ft = tempActivity.getSupportFragmentManager().beginTransaction(); for (int i = 0; i < frags.size(); i++) { ft.remove(frags.get(i)); } ft.commit(); tempActivity.intialiseViewPager(); tempActivity.getTabHost().getTabWidget().removeAllViews(); tempActivity.initialiseTabHost(null); tempActivity.NotifyTabActivityViewPagerAdapter(); } 

当主要的两点是使用FragmentTransactionFragmentManager / SupportFragmentManager删除以前添加的片段,在ViewPager显示正确的片段集合,并在添加新的TabWidget之前从TabWidget删除所有视图。

我不确定你是否解决了这个问题,如果是的话,不要理我的答案 Neron T提供的链接很重要(更重要的是给出的build议不要在外面引用适配器的片段)。

当您使用新数据第二次设置适配器时,由于FragmentPagerAdapter的实现方式,您将继续看到旧的碎片。 当您再次设置适配器时,适配器将首先运行destroyItem()方法,其中的片段将从ViewPager 分离 。 接下来,适配器将运行instantiateItem()方法。 在这个方法中,将对FragmentManager进行检查,看看是否有任何先前的片断不可用。 这个检查会发现旧的碎片(至less对于旧的碎片,这就是为什么你得到新碎片的位置,这是不是在以前的情况下,那时没有任何碎片),因为他们简单地从ViewPager分离(但通过findFragmentByTag()FragmentManager仍然可用)。 如果在FragmentManager没有findFragmentManager 那么将调用getItem()方法,从列表中检索片段。

你应该修改你的代码来删除这些片段的列表引用,还有其他方法可以从ViewPager检索片段 (不是很理想)。 作为一个快速解决scheme,您可以尝试从FragmentManager手动删除旧的FragmentManager (就在设置新的适配器之前),强制ViewPager.instantiateItem()方法始终调用getItem()

 if (activity.getClass() == TabsViewPagerFragmentActivity.class) { application.currentReport = result; Log.d(TAG, "Current report parsed is: "+result); ListFragment<Fragment> frags = ((ViewPagerAdapter)mViewPager.getAdapter()).getFragments(); // getter method in your adapter FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); for (int i = 0; i < mOldTmp.size(); i++) { ft.remove(frags.get(i)); } ft.commit(); ((TabsViewPagerFragmentActivity)activity).intialiseViewPager(); ((TabsViewPagerFragmentActivity)activity).initialiseTabHost(null); ((TabsViewPagerFragmentActivity)activity).NotifyTabActivityViewPagerAdapter(); } 

这没有testing,所以试试看,看看它是否工作。

这个问题有两个解决scheme:

解决scheme1 ​​ – 简单的看到这里: https : //stackoverflow.com/a/13467232/444324

基本上你需要添加这个代码到你的viewpager适配器:

 @Override public int getItemPosition(Object object){ return PagerAdapter.POSITION_NONE; } 

解决scheme2 – 推荐的一个很好的解释在这里: https : //stackoverflow.com/a/8024557/444324

我将发布我的一些代码,以便你会有一些想法。

适配器初始化并将其设置为视图分页器。

 vfPageContainer = (ViewPager)findViewById(R.id.vfPageContainer); mAdapter = new TestFragmentAdapter(this,getSupportFragmentManager()); vfPageContainer.setAdapter(mAdapter); 

每次新数据来了,我打电话给下面的方法:

updateUi()方法

 private void updateUi() { for(int i=0 ; i < alDataPages.size() ; i++) { mAdapter.addFragment(TestFragment.newInstance(this)); } mAdapter.notifyDataSetChanged(); } 

在TestFragmentAdapter类中有添加和清除来自view-pager的片段的方法。

TestFragmentAdapter类

 class TestFragmentAdapter extends FragmentStatePagerAdapter { private Context context; private ArrayList<Fragment> views = new ArrayList<Fragment>(); public TestFragmentAdapter(Context context,FragmentManager fm) { super(fm); this.context = context; views = new ArrayList<Fragment>(); } @Override public Fragment getItem(int position) { return views.get(position); } public void addFragment (Fragment v) { views.add(v); } public void clear() { for(int i = 0 ; i < views.size() ; i++) { views.clear(); } } @Override public int getCount() { return views.size(); } } 

TestFragment类

 public final static class TestFragment extends Fragment { private Context context; public void setContext(Context c) { context = c; } public static TestFragment newInstance(Context context) { TestFragment f = new TestFragment(); f.setContext(context); return f; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { WebView webView_viewpage = new WebView(context); return webView_viewpage; } } 

所以当新的数据来之前,我称之为下面的代码。 我正在从适配器中删除所有的视图,并创build新的1,并将其设置为每次view-pager。你也应该尝试这个代码它应该工作。

  mAdapter.clear(); // previously it was not working so i created new adapter and set it to the viewpager. mAdapter = new TestFragmentAdapter(this,getSupportFragmentManager()); vfPageContainer.setAdapter(mAdapter); 

希望这对你有帮助,你会find解决办法。