java - How do I load data in RecyclerView asynchronously? -


i have blank recycler view inside fragment. upon receiving gcm notification, call webservice. webservice store data blank database. when done, how notify recycler view update new database content?

i stuck @ portion need notify recycler view somehow update itself. implemented https://gist.github.com/skyfishjy/443b7448f59be978bc59, works when there data in database. not work in scenario.

i providing code have better understanding of problem:

package mypackage;  import android.app.activity; import android.app.loadermanager; import android.content.contentresolver; import android.content.contentvalues; import android.content.cursorloader; import android.content.loader; import android.database.cursor; import android.net.uri; import android.os.asynctask; import android.os.bundle; import android.os.handler; import android.support.v4.app.fragment; import android.support.v4.view.viewcompat; import android.support.v7.widget.linearlayoutmanager; import android.support.v7.widget.recyclerview; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.view.animation.overshootinterpolator;  import com.squareup.picasso.picasso;  import mypackage.r; import mypackage.adapters.newsrecyclerviewadapter; import mypackage.database.newsprovider; import mypackage.models.news; import mypackage.utils.saveimagetask;  import java.text.simpledateformat; import java.util.arraylist; import java.util.arrays; import java.util.calendar; import java.util.date; import java.util.list; import java.util.locale; import java.util.random;  import butterknife.butterknife; import jp.wasabeef.recyclerview.animators.flipinrightyanimator; import jp.wasabeef.recyclerview.animators.adapters.alphainanimationadapter; import jp.wasabeef.recyclerview.animators.adapters.scaleinanimationadapter;  import static mypackage.mydbopenhelper.*;   public class newslistfragment extends fragment implements loadermanager.loadercallbacks<cursor> {      private newsrecyclerviewadapter madapter;     private saveimagetask saveimagetask;     private newstype newstype;     private activity parent;      public static newslistfragment newinstance(newstype newstype, activity container) {         newslistfragment fragment = new newslistfragment();         fragment.saveimagetask = new saveimagetask(container);         fragment.newstype = newstype;         fragment.parent = container;         return fragment;     }      @override     public view oncreateview(layoutinflater inflater, viewgroup container,                              final bundle savedinstancestate) {         view view = inflater.inflate(r.layout.recycler_view, container, false);         butterknife.bind(this, view);          final recyclerview mrecyclerview = (recyclerview) view.findviewbyid(r.id.my_recycler_view);         mrecyclerview.sethasfixedsize(true);         recyclerview.layoutmanager mlayoutmanager = new linearlayoutmanager(view.getcontext());         mrecyclerview.setlayoutmanager(mlayoutmanager);          picasso picasso = new picasso.builder(parent).build();         contentresolver contentresolver = parent.getcontentresolver();         cursor newscursor;         if (newstype == newstype.all) {             newscursor = contentresolver.query(newsprovider.content_uri, null, null, null, null);         } else {             newscursor = contentresolver.query(savednewsprovider.content_uri, null, null, null, null);         }          madapter = new newsrecyclerviewadapter(newscursor);         madapter.setpicasso(picasso);          alphainanimationadapter alphaadapter = new alphainanimationadapter(madapter);         scaleinanimationadapter scaleadapter = new scaleinanimationadapter(alphaadapter);         scaleadapter.setfirstonly(false);         scaleadapter.setinterpolator(new overshootinterpolator());         mrecyclerview.setitemanimator(new flipinrightyanimator());         mrecyclerview.getitemanimator().setaddduration(300);          mrecyclerview.setadapter(scaleadapter);          viewcompat.setelevation(view, 50);         parent.getloadermanager().initloader(0, null, this);          new asynctask<void, void, void>() {             @override             protected void doinbackground(void... params) {                 cursor news = parent.getcontentresolver().query(newsprovider.content_uri,                         null, null, null, null);                 if (news == null || news.getcount() == 0) {                     insertnewslist();                 } else {                     news.close();                 }                 return null;             }              @override             protected void onpostexecute(void avoid) {                 parent.getloadermanager().restartloader(0, null, newslistfragment.this);                 madapter.notifydatasetchanged();                 contentresolver.requestsync(null, newsprovider.authority, new bundle());                 mrecyclerview.refreshdrawablestate();                 mrecyclerview.postinvalidate();             }         }.execute(null, null, null);           return view;     }      private void insertnewslist() {         string[] titles = {"web", "java", "android"};         random random = new random(calendar.getinstance().gettimeinmillis());         (string title : titles) {             int count = random.nextint(20);             list<news> newslist = generatedataset(title, count);             (news dataobject : newslist) {                 contentvalues initialvalues = new contentvalues();                 initialvalues.put(news_image_link, dataobject.gettopimagelink());                 initialvalues.put(news_image_path, dataobject.gettopimagepath());                 initialvalues.put(news_link, dataobject.getlink());                 initialvalues.put(news_source, dataobject.getsourcetext());                 initialvalues.put(news_source_img_link, dataobject.getsourceimagelink());                 initialvalues.put(news_source_img_path, dataobject.getsourceimagepath());                 initialvalues.put(news_tags, arrays.tostring(dataobject.gettag()));                 initialvalues.put(news_text, dataobject.gettext());                 initialvalues.put(news_time, getdatetime());                 initialvalues.put(news_title, dataobject.gettitle());                 parent.getcontentresolver().insert(newsprovider.content_uri, initialvalues);             }         }     }      @override     public void ondestroy() {         super.ondestroy();     }      @override     public loader<cursor> oncreateloader(int id, bundle args) {         return new cursorloader(parent, newsprovider.content_uri, null, null, null, null);     }      @override     public void onloadfinished(loader<cursor> loader, cursor data) {         madapter.swapcursor(data);     }      @override     public void onloaderreset(loader<cursor> loader) {         madapter.swapcursor(null);     }        private list<news> generatedataset(string subject, int count) {         string title = "neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...";         string text = "lorem ipsum dolor sit amet, consectetur adipiscing elit. pellentesque porttitor nulla nec nulla fermentum, " +                 "quis imperdiet ipsum aliquet. phasellus quis odio sit amet nulla rutrum porta. quisque in ultrices metus." +                 " aliquam gravida et lacus ac vestibulum.";          string topimagelink = "http://lorempixel.com/1024/768/";         string[] categories = {"abstract", "city", "people", "transport", "animals",                 "food", "nature", "business", "nightlife", "sports", "cats", "fashion", "technics"};         string sourceimagelink = "http://thegg.net/wp-content/themes/orizon/css/blue_css/images/rss-icon.png";         string sourcetext = "random blog";         string link = "http://www.google.com";          list<news> results = new arraylist<>();         (int index = 0; index < count; index++) {              int imgindex = index % 12;              string imgtext = subject + "-card-" + index;             string newtitle = imgtext + " " + title;              news obj = new news(newtitle);             if (index % 2 == 0) {                 obj.settext(text);             } else {                 obj.settopimagelink(topimagelink + categories[imgindex] + "/" + imgtext);             }              if (index % 5 != 0) {                 obj.setsourceimagelink(sourceimagelink);                 obj.setsourcetext(sourcetext);             }              if (index % 7 == 0) {                 obj.settext(text);                 obj.settopimagelink(topimagelink + categories[imgindex] + "/" + imgtext);                 obj.setsourceimagelink(sourceimagelink);                 obj.setsourcetext(sourcetext);             }              if (obj.gettopimagelink() != null && !"".equalsignorecase(obj.gettopimagelink())) {                 uri topimageuri = saveimagetask.saveimagefile(obj.gettopimagelink());                 obj.settopimagepath(topimageuri.getpath());             }              if (obj.getsourceimagelink() != null && !"".equalsignorecase(obj.getsourceimagelink())) {                 uri sourceimageuri = saveimagetask.saveimagefile(obj.getsourceimagelink());                 obj.setsourceimagepath(sourceimageuri.getpath());             }              obj.setlink(link);             obj.settag(new string[] {subject});             results.add(index, obj);         }         return results;     }      private string getdatetime() {         simpledateformat dateformat = new simpledateformat(                 "yyyy-mm-dd hh:mm:ss", locale.getdefault());         date date = new date();         return dateformat.format(date);     }      public enum newstype {         all,         favorite     } } 

my contentprovider

package mypackage.database;  import android.content.contentprovider; import android.content.contentvalues; import android.database.sqlite.sqlitedatabase; import android.net.uri;  public abstract class newsprovider extends contentprovider {      public static final string authority = "myapp.data.newsprovider";     private static final string base_path = "news";     public static final uri content_uri = uri.parse("content://" + authority + "/" + base_path );      // constant identify requested operation     private static final int news = 1;     private static final int news_id = 2;     private static final int news_tag = 3;     private static final urimatcher urimatcher = new urimatcher(urimatcher.no_match);      static {         urimatcher.adduri(authority, base_path, news);         urimatcher.adduri(authority, base_path + "/#", news_id);         urimatcher.adduri(authority, base_path + "/tag/*", news_tag);     }      private string tablename;     private string basepath;     protected sqlitedatabase database;      public newsprovider() {         this.tablename = table_news;         this.basepath = base_path;     }      @override     public boolean oncreate() {         mydbopenhelper helper = new mydbopenhelper(getcontext());         database = helper.getwritabledatabase();         return true;     }      @override     public string gettype(uri uri) {         return null;     }      @override     public cursor query(uri uri, string[] projection, string selection, string[] selectionargs, string sortorder) {         if (urimatcher.match(uri) == news_id) {             selection = news_id + "=" + uri.getlastpathsegment();         }          if (urimatcher.match(uri) == news_tag) {             selection = news_tags + " %'" + uri.getlastpathsegment() + "'%";         }          return database.query(table_news, news_all_columns,                 selection, null, null, null, news_time + " desc");     }      @override     public uri insert(uri uri, contentvalues values) {         long id = database.insert(tablename, null, values);         uri newuri = uri.parse(basepath + "/" + id);         getcontext().getcontentresolver().notifychange(newuri, null);         return newuri;     }      @override     public int delete(uri uri, string selection, string[] selectionargs) {         return database.delete(tablename, selection, selectionargs);     }      @override     public int update(uri uri, contentvalues values, string selection, string[] selectionargs) {         return database.update(tablename, values, selection, selectionargs);     } } 

i stuck @ portion need notify recycler view somehow update itself. implemented https://gist.github.com/skyfishjy/443b7448f59be978bc59, works when there data in database. not work in scenario.

if have contentprovider , using cursorloader, upon notify of correct uri, framework should query database again. if not using contentprovider, use localbroadcastmanger, broadcast event after insertion of new data in database. fragment should register event , re-query database manually


Comments

Popular posts from this blog

java - Date formats difference between yyyy-MM-dd'T'HH:mm:ss and yyyy-MM-dd'T'HH:mm:ssXXX -

c# - Get rid of xmlns attribute when adding node to existing xml -