android - how to save listview items/adapter in fragment and restore from back stack -
i've been tried search problem couldn't solution. i've got problem saving listview items in fragment. case have several fragments
let fragment a, fragment b , fragment c, , fragment has listview, item of listview can changed when user scroll (just timeline in social media apps). when change fragment a, used addtobackstack(null) method.
the problem is, how save listview , restore if button pressed?
onsaveinstancestate() never called because activity host never killed, change fragment using this:
public void changefragment(fragment fragment, colordrawable colordrawable){ fragment newfrag = fragment; colordrawable newcolor = colordrawable; string backstatename = fragment.getclass().getname(); fragmentmanager manager = getsupportfragmentmanager(); boolean fragmentpopped = manager.popbackstackimmediate (backstatename, 0); if (!fragmentpopped){ //fragment not in stack, create it. fragmenttransaction ft = manager.begintransaction(); ft.replace(r.id.content_fragment, fragment); ft.addtobackstack(backstatename); ft.commit(); } //to change actionbar color getsupportactionbar().setbackgrounddrawable(newcolor); }
here code trying save , restore listview:
@override public void ondestroyview() { super.ondestroyview(); //try save listview scroll index = mylist.getfirstvisibleposition(); view v = mylist.getchildat(0); top = (v == null) ? 0 : (v.gettop() - mylist.getpaddingtop()); index = 1; //try save listview items savedadapter = adapter; frombackstack = true; } @override public void onactivitycreated(bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); mylist.setselectionfromtop(index, top); mylist.setadapter(savedadapter); }
here code i've done far :
package com.ngapainya.ngapainya.fragment; import android.app.activity; import android.graphics.drawable.colordrawable; import android.net.parseexception; import android.os.asynctask; import android.os.bundle; import android.support.v4.app.fragment; import android.support.v4.app.fragmentactivity; import android.support.v4.widget.swiperefreshlayout; import android.util.log; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.abslistview; import android.widget.adapterview; import android.widget.listview; import com.ngapainya.ngapainya.r; import com.ngapainya.ngapainya.activity.volunteer.containeractivity; import com.ngapainya.ngapainya.adapter.homeadapter; import com.ngapainya.ngapainya.fragment.child.detailpostfragment; import com.ngapainya.ngapainya.model.home; import java.util.arraylist; /** * simple {@link fragment} subclass. */ public class homefragment extends fragment implements adapterview.onitemclicklistener, swiperefreshlayout.onrefreshlistener{ private fragmentactivity mycontext; private view myfragmentview; private arraylist<home> filelist; private listview mylist; private homeadapter adapter; private swiperefreshlayout swiperefreshlayout; //try save instance listview boolean frombackstack = false; int index; int top; homeadapter savedadapter; @override public void ondestroyview() { super.ondestroyview(); //try save listview scroll index = mylist.getfirstvisibleposition(); view v = mylist.getchildat(0); top = (v == null) ? 0 : (v.gettop() - mylist.getpaddingtop()); index = 1; //try save listview items savedadapter = adapter; frombackstack = true; } @override public void onactivitycreated(bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); mylist.setselectionfromtop(index, top); mylist.setadapter(savedadapter); } @override public void onattach(activity activity) { mycontext = (fragmentactivity) activity; super.onattach(activity); } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { // inflate layout fragment myfragmentview = inflater.inflate(r.layout.fragment_home, container, false); filelist = new arraylist<home>(); //dummy data filelist.add(new home("post", 1)); //post image filelist.add(new home("post", 2)); //post location filelist.add(new home("post", 3)); //post url filelist.add(new home("post", 4)); //become friend filelist.add(new home("post", 0)); //post status swiperefreshlayout = (swiperefreshlayout) myfragmentview.findviewbyid(r.id.swipe_refresh_layout); swiperefreshlayout.setonrefreshlistener(this); /** * showing swipe refresh animation on activity create * animation won't start on oncreate, post runnable used */ swiperefreshlayout.post(new runnable() { @override public void run() { swiperefreshlayout.setrefreshing(true); //do swiperefreshlayout.setrefreshing(false); } } ); mylist = (listview) myfragmentview.findviewbyid(r.id.list_home); //mylist.setadapter(new homeadapter(mycontext, filelist)); adapter = new homeadapter(mycontext, filelist); mylist.setonitemclicklistener(this); if(!frombackstack) { new remotedatatask().execute(); } return myfragmentview; } /** * method called when swipe refresh pulled down */ @override public void onrefresh() { //do mylist.setadapter(adapter); arraylist<home> new_filelist = new arraylist<>(); new_filelist.add(new home("post", 4)); filelist.addall(0, new_filelist); adapter.notifydatasetchanged(); swiperefreshlayout.setrefreshing(false); } @override public void onitemclick(adapterview<?> parent, view view, int position, long id) { home tmp = (home) parent.getitematposition(position); detailpostfragment detailpostfragment = new detailpostfragment(); bundle args = new bundle(); switch (tmp.type) { case 0: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 1: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 2: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 3: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 4: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; } } private class remotedatatask extends asynctask<string, void, arraylist<home>> { @override protected void onpreexecute() { super.onpreexecute(); } @override protected arraylist<home> doinbackground(string... urls) { try { arraylist<home> new_filelist = new arraylist<home>(); new_filelist.add(new home("post", 3)); //post url new_filelist.add(new home("post", 4)); //become friend new_filelist.add(new home("post", 0)); //post status filelist.addall(new_filelist); } catch (parseexception e) { log.e("error", e.getmessage()); e.printstacktrace(); } return filelist; } @override protected void onpostexecute(arraylist<home> organization) { mylist.setadapter(new homeadapter(mycontext, filelist)); // create onscrolllistener mylist.setonscrolllistener(new abslistview.onscrolllistener() { @override public void onscrollstatechanged(abslistview view, int scrollstate) { // todo auto-generated method stub int threshold = 1; int count = mylist.getcount(); if (scrollstate == scroll_state_idle) { if (mylist.getlastvisibleposition() >= count - threshold) { // execute loadmoredatatask asynctask new loadmoredatatask().execute(); } } } @override public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { // todo auto-generated method stub } }); } } public class loadmoredatatask extends asynctask<string, void, arraylist<home>> { @override protected void onpreexecute() { super.onpreexecute(); } @override protected arraylist<home> doinbackground(string... urls) { try { // web service request arraylist<home> new_filelist = new arraylist<home>(); new_filelist.add(new home("post", 0)); //post status if(new_filelist != null && new_filelist.size() > 0 ){ filelist.addall(new_filelist); } } catch (exception e) { e.printstacktrace(); } return filelist; } @override protected void onpostexecute(arraylist<home> organization) { int position = mylist.getlastvisibleposition(); adapter = new homeadapter(mycontext, filelist); mylist.setadapter(adapter); adapter.notifydatasetchanged(); mylist.setselectionfromtop(position, 0); } } }
i hope me out, thank .
updated code code far, works when try saved listview items , adapter, perhaps bit tricky. if has idea appreciated.
package com.ngapainya.ngapainya.fragment; import android.app.activity; import android.graphics.drawable.colordrawable; import android.net.parseexception; import android.os.asynctask; import android.os.bundle; import android.support.v4.app.fragment; import android.support.v4.app.fragmentactivity; import android.support.v4.widget.swiperefreshlayout; import android.util.log; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.abslistview; import android.widget.adapterview; import android.widget.listview; import com.ngapainya.ngapainya.r; import com.ngapainya.ngapainya.activity.volunteer.containeractivity; import com.ngapainya.ngapainya.adapter.homeadapter; import com.ngapainya.ngapainya.fragment.child.detailpostfragment; import com.ngapainya.ngapainya.model.home; import java.util.arraylist; /** * simple {@link fragment} subclass. */ public class homefragment extends fragment implements adapterview.onitemclicklistener, swiperefreshlayout.onrefreshlistener{ private fragmentactivity mycontext; private view myfragmentview; private arraylist<home> filelist; private listview mylist; private homeadapter adapter; private swiperefreshlayout swiperefreshlayout; /* * these variables used restore listview * when calling fragment backstack * */ private boolean frombackstack = false; private homeadapter savedadapter; private arraylist<home> savedfilelist; @override public void ondestroyview() { super.ondestroyview(); savedadapter = adapter; savedfilelist = filelist; frombackstack = true; log.e("ondestroyview", "ondestroyview"); } @override public void onattach(activity activity) { mycontext = (fragmentactivity) activity; super.onattach(activity); } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { // inflate layout fragment myfragmentview = inflater.inflate(r.layout.fragment_home, container, false); log.e("oncreateview", "oncreateview"); swiperefreshlayout = (swiperefreshlayout) myfragmentview.findviewbyid(r.id.swipe_refresh_layout); swiperefreshlayout.setonrefreshlistener(this); /** * showing swipe refresh animation on activity create * animation won't start on oncreate, post runnable used */ /*swiperefreshlayout.post(new runnable() { @override public void run() { swiperefreshlayout.setrefreshing(true); //do swiperefreshlayout.setrefreshing(false); } } );*/ mylist = (listview) myfragmentview.findviewbyid(r.id.list_home); //mylist.setadapter(new homeadapter(mycontext, filelist)); mylist.setonitemclicklistener(this); filelist = new arraylist<home>(); adapter = new homeadapter(mycontext, filelist); if(frombackstack) { filelist = savedfilelist; adapter = savedadapter; } new remotedatatask().execute(); return myfragmentview; } /** * method called when swipe refresh pulled down */ @override public void onrefresh() { arraylist<home> new_filelist = new arraylist<>(); new_filelist.add(new home("post", 4)); filelist.addall(0, new_filelist); adapter.notifydatasetchanged(); swiperefreshlayout.setrefreshing(false); log.e("onrefresh", "onrefresh"); } /* * method called whenever listview item clicked * */ @override public void onitemclick(adapterview<?> parent, view view, int position, long id) { home tmp = (home) parent.getitematposition(position); detailpostfragment detailpostfragment = new detailpostfragment(); bundle args = new bundle(); switch (tmp.type) { case 0: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 1: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 2: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 3: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; case 4: args.putint("posttype", tmp.type); detailpostfragment.setarguments(args); ((containeractivity) getactivity()).changefragment(detailpostfragment, new colordrawable(getresources().getcolor(r.color.colorprimary))); break; } } /* * method called in oncreateview method * used load data server , populate them * listview * */ private class remotedatatask extends asynctask<string, void, arraylist<home>> { @override protected void onpreexecute() { super.onpreexecute(); } @override protected arraylist<home> doinbackground(string... urls) { try { arraylist<home> new_filelist = new arraylist<home>(); //dummy data new_filelist.add(new home("post", 1)); //post image new_filelist.add(new home("post", 2)); //post location new_filelist.add(new home("post", 3)); //post url new_filelist.add(new home("post", 4)); //become friend new_filelist.add(new home("post", 0)); //post status new_filelist.add(new home("post", 3)); //post url new_filelist.add(new home("post", 4)); //become friend new_filelist.add(new home("post", 0)); //post status filelist.addall(new_filelist); } catch (parseexception e) { log.e("error", e.getmessage()); e.printstacktrace(); } return filelist; } @override protected void onpostexecute(arraylist<home> organization) { mylist.setadapter(adapter); // create onscrolllistener mylist.setonscrolllistener(new abslistview.onscrolllistener() { @override public void onscrollstatechanged(abslistview view, int scrollstate) { // todo auto-generated method stub int threshold = 1; int count = mylist.getcount(); if (scrollstate == scroll_state_idle) { if (mylist.getlastvisibleposition() >= count - threshold) { // execute loadmoredatatask asynctask new loadmoredatatask().execute(); } } } @override public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { // todo auto-generated method stub } }); } } /* * method called when listview pulled down * trigger method load more items server * */ public class loadmoredatatask extends asynctask<string, void, arraylist<home>> { @override protected void onpreexecute() { super.onpreexecute(); } @override protected arraylist<home> doinbackground(string... urls) { try { // web service request arraylist<home> new_filelist = new arraylist<home>(); new_filelist.add(new home("post", 0)); //post status new_filelist.add(new home("post", 1)); if(new_filelist != null && new_filelist.size() > 0 ){ filelist.addall(new_filelist); } } catch (exception e) { e.printstacktrace(); } return filelist; } @override protected void onpostexecute(arraylist<home> organization) { int position = mylist.getlastvisibleposition(); //adapter = new homeadapter(mycontext, filelist); mylist.setadapter(adapter); adapter.notifydatasetchanged(); mylist.setselectionfromtop(position, 0); } } }
finally figured out... don't know whether best solution or not works far me. need 1 method , several variables, this.
@override public void ondestroyview() { super.ondestroyview(); savedadapter = adapter; savedfilelist = filelist; frombackstack = true; log.e("ondestroyview", "ondestroyview"); }
thanks so.
Comments
Post a Comment