Android-viewpager+fragment Data Update issues

Source: Internet
Author: User

Because the cache exists inside the fragmentpageradapter, calling notifydatasetchanged () does not allow the fragment to be updated.

Reference: http://www.devba.com/index.php/archives/5826.html

http://stackoverflow.com/questions/7263291/viewpager-pageradapter-not-updating-the-view/7287121#7287121

There are two ways to solve this problem:

(1) Rewrite adapter's getitemposition ():

public int GetItemPosition (Object object) {    return position_none;}
When Notifydatasetchanged () is called, Viewpager will remove all view and reload. feasible, but inefficient.

(2) On the view Settag, then use Viewpager.findviewwithtag () to find the view to update, and then do the update.

Because the Fragmentpageradapter internal cache fragment, is already in accordance with the tag cache, so, in the update, we just according to tag, get fragment, and then go to update fragment on it.

Take a look at Fragmentpageradapter's Instantiateitem () method:

public Object instantiateitem (viewgroup container, int position) {if (this.mcurtransact    Ion = = null) {this.mcurtransaction = This.mFragmentManager.beginTransaction ();    } Long itemId = Getitemid (position); String name = Makefragmentname (Container.getid (), itemId);//Here is the tag Fragment Fragment = This.mfragmentmana in generating Fragment Ger.findfragmentbytag (name);//This is based on tag lookup if (fragment! = null) {This.mCurTransaction.attach (fragment);//Find direct at TCH} else {fragment = GetItem (position);//When not found, the GetItem This.mCurTransaction.add is called (Container.getid (), FR    Agment, Makefragmentname (Container.getid (), itemId));      } if (Fragment! = This.mcurrentprimaryitem) {fragment.setmenuvisibility (false);    Fragment.setuservisiblehint (FALSE);  } return fragment; }
According to the original code we can know that the system to each fragment a label, through the label to find the corresponding fragment, so when we enter fragment the second time, fragment OnCreate, The Oncreateview method is not called because the GetItem () method in Fragmentpageadapter is not called at all, because the system will find the corresponding fragment based on the label, and if it already exists, it will not be called. Fragment has a caching mechanism here.
Now the problem is that you have to do the update, so you can:

public class Fragmentviewpageradapter extends Fragmentpageradapter {private Fragmentmanager mfragmentmanager;private list<string> mdatas;private list<string> tagList = new arraylist<string> ();p ublic Fragmentviewpageradapter (Fragmentmanager FM, list<string> datas) {super (FM); this.mfragmentmanager = FM; This.mdatas = datas;} @Overridepublic Object Instantiateitem (viewgroup container, int position) {Taglist.add (Makefragmentname (Contai Ner.getid (), getitemid (position));        Save the tag to 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)));//delete tag}@ Overridepublic Fragment getItem (int position) {String URL = mdatas.get (position); WebViewFragmentV4 WebView = new WebViewFragmentV4 (URL);//The fragment tested in this article is a 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 ();//does not play a role in updating fragment content. }public void Update (int position) {//This thing really updates the contents of 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 are 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 have 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 on 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);} }}

Reprint please indicate source: http://blog.csdn.net/goldenfish1919/article/details/47661443

Test code:

1. Initialize Viewpager = (Viewpager) This.findviewbyid (r.id.viewpager); adapter = new Fragmentviewpageradapter ( Getsupportfragmentmanager (), null); Viewpager.setadapter (adapter);//2. Load data 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. Do update 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); a Dapter.update (3);//Reload Position 3 page}});

Refactor:

(1) Basefragmentpageradapter.java

Public abstract class Basefragmentpageradapter extends Fragmentpageradapter{private Fragmentmanager Mfragmentmanager; Private list<string> tagList = new arraylist<string> ();p ublic basefragmentpageradapter (fragmentmanager FM ) {super (FM); this.mfragmentmanager = FM;} @Overridepublic Object Instantiateitem (viewgroup container, int position) {Taglist.add (Makefragmentname (Contai            Ner.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) {//The only requirement here is fragment to implement the Updateable Interface ((updateable) fragment). Update ();}} Public interface updateable {public void update ();}}
Later our adapter as long as inherit basefragmentpageradapter to be able, for example:

(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 ();}}
As with normal usage, the only requirement is that the fragment must implement the updateable interface, perfect!


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Android-viewpager+fragment Data Update issues

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.