因爲FragmentPagerAdapter內部存在緩存。所以調用notifyDataSetChanged()並不能夠去更新Fragment的內容。php
參考:http://www.devba.com/index.php/archives/5826.htmlhtml
可以有兩種解決的方法:android
(1)重寫Adapter的getItemPosition():web
public int getItemPosition(Object object) { return POSITION_NONE; }當調用notifyDataSetChanged()的時候。ViewPager會remove掉所有的view,而後又一次去載入。可行,但是效率低。
(2)在view上調用SetTag。而後用ViewPager.findViewWithTag()來找到要更新的view,而後作更新。緩存
因爲FragmentPagerAdapter內部緩存Fragment的時候,已是依照tag的方式緩存的,所以。在更新的時候,咱們僅僅要依據tag,拿到fragment,而後去更新fragment就可以了。jsp
看下FragmentPagerAdapter的instantiateItem()方法:ide
public Object instantiateItem(ViewGroup container, int position) { if (this.mCurTransaction == null) { this.mCurTransaction = this.mFragmentManager.beginTransaction(); } long itemId = getItemId(position); String name = makeFragmentName(container.getId(), itemId);//這裏就是在生成fragment的tag Fragment fragment = this.mFragmentManager.findFragmentByTag(name);//這裏是依據tag查找 if (fragment != null) { this.mCurTransaction.attach(fragment);//找到直接attch } else { fragment = getItem(position);//找不到的時候。纔會調用getItem this.mCurTransaction.add(container.getId(), fragment, makeFragmentName(container.getId(), itemId)); } if (fragment != this.mCurrentPrimaryItem) { fragment.setMenuVisibility(false); fragment.setUserVisibleHint(false); } return fragment; }依據原代碼咱們可以知道系統給每一個Fragment都打上了一個標籤,經過標籤來尋找對應的fragment,因此當咱們第二次進入fragment的時候。fragment的oncreate,oncreateView方法都不會被調用的。因爲FragmentPageAdapter中的getitem()方法根本不會被調用,因爲系統會依據標籤找到對應的fragment。假設已經存在,就不會被調用,fragment有一個緩存機制在這裏。
現在的問題是必須要作更新,那麼可以這麼弄: post
public class FragmentViewPagerAdapter extends FragmentPagerAdapter { private FragmentManager mFragmentManager; private List<String> mDatas; private List<String> tagList = new ArrayList<String>(); public FragmentViewPagerAdapter(FragmentManager fm, List<String> datas) { super(fm); this.mFragmentManager = fm; this.mDatas = datas; } @Override public Object instantiateItem(ViewGroup container, int position) { tagList.add(makeFragmentName(container.getId(), getItemId(position))); //把tag存起來 return super.instantiateItem(container, position); } @Override public void destroyItem(ViewGroup container, int position, Object object){ super.destroyItem(container, position, object); tagList.remove(makeFragmentName(container.getId(), getItemId(position)));//把tag刪掉 } @Override public Fragment getItem(int position) { String url = mDatas.get(position); WebViewFragmentV4 webview = new WebViewFragmentV4(url);//本文測試的Fragment是一個WebViewFragment
return webview; } @Override public int getCount() { if (mDatas == null) { return 0; } else { return mDatas.size(); } } public void update(List<String> datas){ this.mDatas = datas; notifyDataSetChanged();//並不能起到更新Fragment內容的做用。WebViewFragmentV4.java:} public void update(int position){//這個事真正的更新Fragment的內容 WebViewFragmentV4 fragment = (WebViewFragmentV4)mFragmentManager.findFragmentByTag(tagList.get(position)); if(fragment == null){ return; } fragment.update(); } private static String makeFragmentName(int viewId, long id) { return "android:switcher:" + viewId + ":" + id; } } this
public class WebViewFragmentV4 extends Fragment { private WebView mWebView; private boolean mIsWebViewAvailable; private String mUrl; public WebViewFragmentV4(String url) { this.mUrl = url; } /** * Called to instantiate the view. Creates and returns the WebView. */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (mWebView != null) { mWebView.destroy(); } mWebView = new WebView(getActivity()); mWebView.getSettings().setUseWideViewPort(true); mWebView.getSettings().setLoadWithOverviewMode(true); mWebView.setWebViewClient(new MyWebViewClient()); mWebView.loadUrl(mUrl); mIsWebViewAvailable = true; return mWebView; } /** * Called when the fragment is visible to the user and actively running. * Resumes the WebView. */ @Override public void onPause() { super.onPause(); mWebView.onPause(); } /** * Called when the fragment is no longer resumed. Pauses the WebView. */ @Override public void onResume() { mWebView.onResume(); super.onResume(); } /** * Called when the WebView has been detached from the fragment. The WebView * is no longer available after this time. */ @Override public void onDestroyView() { mIsWebViewAvailable = false; super.onDestroyView(); } /** * Called when the fragment is no longer in use. Destroys the internal state * of the WebView. */ @Override public void onDestroy() { if (mWebView != null) { mWebView.destroy(); mWebView = null; } super.onDestroy(); } public void update(){ if (mWebView != null) { mWebView.reload(); } } /** * Gets the WebView. */ public WebView getWebView() { return mIsWebViewAvailable ? mWebView : null; } private static class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); } } }
轉載請標明出處:http://blog.csdn.net/goldenfish1919/article/details/47661443
測試代碼:
//1. 初始化 viewpager = (ViewPager)this.findViewById(R.id.viewpager); adapter = new FragmentViewPagerAdapter(getSupportFragmentManager(), null); viewpager.setAdapter(adapter); //2. 載入數據 List<String> urls = new ArrayList<String>(); urls.add("http://172.16.28.253:8080/web/1.jsp"); urls.add("http://172.16.28.253:8080/web/2.jsp"); urls.add("http://172.16.28.253:8080/web/3.jsp"); urls.add("http://172.16.28.253:8080/web/4.jsp"); adapter.update(urls); //3. 作更新 Button update = (Button) this.findViewById(R.id.update); update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(viewpager != null && adapter != null){ viewpager.setCurrentItem(3, true); adapter.update(3);//又一次載入position是3的頁面 } } });
重構一下:
(1)BaseFragmentPagerAdapter.java
public abstract class BaseFragmentPagerAdapter extends FragmentPagerAdapter{ private FragmentManager mFragmentManager; private List<String> tagList = new ArrayList<String>(); public BaseFragmentPagerAdapter(FragmentManager fm) { super(fm); this.mFragmentManager = fm; } @Override public Object instantiateItem(ViewGroup container, int position) { tagList.add(makeFragmentName(container.getId(), getItemId(position))); return super.instantiateItem(container, position); } @Override public void destroyItem(ViewGroup container, int position, Object object){ super.destroyItem(container, position, object); tagList.remove(makeFragmentName(container.getId(), getItemId(position))); } private static String makeFragmentName(int viewId, long id) { return "android:switcher:" + viewId + ":" + id; } public void update(int position){ Fragment fragment = (Fragment)mFragmentManager.findFragmentByTag(tagList.get(position)); if(fragment == null){ return; } if(fragment instanceof UpdateAble){//這裏惟一的要求是Fragment要實現UpdateAble接口 ((UpdateAble)fragment).update(); } } public interface UpdateAble { public void update(); } }之後咱們的Adapter僅僅要繼承BaseFragmentPagerAdapter就可以了。比方:
(2)FragmentViewPagerAdapter.java
public class FragmentViewPagerAdapter extends BaseFragmentPagerAdapter { private List<String> mDatas; public FragmentViewPagerAdapter(FragmentManager fm, List<String> datas) { super(fm); this.mDatas = datas; } @Override public Fragment getItem(int position) { String url = mDatas.get(position); WebViewFragmentV4 webview = new WebViewFragmentV4(url); return webview; } @Override public int getCount() { if (mDatas == null) { return 0; } else { return mDatas.size(); } } public void update(List<String> datas){ this.mDatas = datas; notifyDataSetChanged(); } }跟普通的使用方法同樣。惟一的要求是。Fragment必須要實現UpdateAble接口,perfect!