標籤:代碼 position mda called array bst map eof arraylist
由於FragmentPagerAdapter內部存在緩衝。因此調用notifyDataSetChanged()並不可以去更新Fragment的內容。
參考:http://www.devba.com/index.php/archives/5826.html
http://stackoverflow.com/questions/7263291/viewpager-pageradapter-not-updating-the-view/7287121#7287121
能夠有兩種解決的方法:
(1)重寫Adapter的getItemPosition():
public int getItemPosition(Object object) { return POSITION_NONE;}當調用notifyDataSetChanged()的時候。ViewPager會remove掉全部的view,然後又一次去載入。可行,可是效率低。
(2)在view上調用SetTag。然後用ViewPager.findViewWithTag()來找到要更新的view,然後做更新。
由於FragmentPagerAdapter內部緩衝Fragment的時候,已經是依照tag的方式緩衝的,因此。在更新的時候,我們僅僅要依據tag,拿到fragment,然後去更新fragment就能夠了。
看下FragmentPagerAdapter的instantiateItem()方法:
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有一個緩衝機制在這裡。
如今的問題是必需要做更新,那麼能夠這麼弄:
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;}@Overridepublic Object instantiateItem(ViewGroup container, int position) { tagList.add(makeFragmentName(container.getId(), getItemId(position))); //把tag存起來 return super.instantiateItem(container, position); } @Overridepublic void destroyItem(ViewGroup container, int position, Object object){super.destroyItem(container, position, object);tagList.remove(makeFragmentName(container.getId(), getItemId(position)));//把tag刪掉}@Overridepublic Fragment getItem(int position) {String url = mDatas.get(position);WebViewFragmentV4 webview = new WebViewFragmentV4(url);//本文測試的Fragment是一個WebViewFragment
return webview;}@Overridepublic int getCount() {if (mDatas == null) {return 0;} else {return mDatas.size();}}public void update(List<String> datas){this.mDatas = datas;notifyDataSetChanged();//並不能起到更新Fragment內容的作用。}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;}}
WebViewFragmentV4.java:
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. */@Overridepublic 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. */@Overridepublic void onPause() {super.onPause();mWebView.onPause();}/** * Called when the fragment is no longer resumed. Pauses the WebView. */@Overridepublic 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. */@Overridepublic void onDestroyView() {mIsWebViewAvailable = false;super.onDestroyView();}/** * Called when the fragment is no longer in use. Destroys the internal state * of the WebView. */@Overridepublic 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 {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {view.loadUrl(url);return true;}@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {super.onPageStarted(view, url, favicon);}@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);}@Overridepublic 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() {@Overridepublic 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;}@Overridepublic Object instantiateItem(ViewGroup container, int position) { tagList.add(makeFragmentName(container.getId(), getItemId(position))); return super.instantiateItem(container, position); } @Overridepublic 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;}@Overridepublic Fragment getItem(int position) {String url = mDatas.get(position);WebViewFragmentV4 webview = new WebViewFragmentV4(url);return webview;}@Overridepublic int getCount() {if (mDatas == null) {return 0;} else {return mDatas.size();}}public void update(List<String> datas){this.mDatas = datas;notifyDataSetChanged();}}跟普通的使用方法一樣。唯一的要求是。Fragment必需要實現UpdateAble介面,perfect!
Android-ViewPager+Fragment資料更新問題