Harish Kamboj Harish Kamboj - 4 months ago 42
Android Question

Adding data dynamically from SQLite to top of recyclerview

I am trying to implement swipe to refresh in my app. When swipe to refresh is triggered, first all the data is fetched from JSON and then stored in the database. After storing the data, all the new data will be added to the top of the recyclerview. I read a few articles and only managed to find out about adding a single item at the top of the list. But in the case of my app, where more than one item may be available to show, what should I do?

Here is my code for the database table where first new post is fetched with the last post id which is shown in recyclerview:

@Override
public ArrayList<Post> getAllNewPost(int T) {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<Post> postList = null;
try {
postList = new ArrayList<Post>();

String QUERY = "SELECT * FROM " + TABLE_NAME + " INNER JOIN "+TABLE_FOLLOWER+
" ON post_table.user_id = follower.user_id WHERE follower.follow = '1' AND post_table.post_id > "+T+" ORDER BY "+POST_ID+" DESC";
Cursor cursor = db.rawQuery(QUERY, null);
if (!cursor.isLast()) {
while (cursor.moveToNext()) {
Post post = new Post();
post.setPost_id(cursor.getString(0));
Log.d("post_id",cursor.getString(0));
post.setUser_id(cursor.getString(1));
post.setUser_name(cursor.getString(2));
post.setImg_link(cursor.getString(3));
post.setPost_title(cursor.getString(4));
post.setPost_cat(cursor.getString(6));
post.setPost_time(cursor.getString(8));
postList.add(post);
}
}
db.close();
} catch (Exception e) {
Log.e("error", e + "");
}
return postList;
}


Here is array adapter of recyclerview:

public class PostAdapter extends RecyclerView.Adapter<PostAdapter.ViewHolder> {

Context context;
ArrayList<Post> listData = new ArrayList<>();
String rpostid,ruserid,rname,rcat,rdate,rtittle,urlThumnail;
private VolleySingleton volleySingleton;
ImageLoader imageLoader = VolleySingleton.getsInstance().getImageLoad();

public PostAdapter(ArrayList<Post> postList) {
this.listData=postList;
}

public PostAdapter(Context context){
this.context = context;
}

@Override
public PostAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.post_item, viewGroup, false);
return new posts(v);
}

public class posts extends ViewHolder {
TextView tvTittle,tvPostId,tvUseId,tvName,tvCat,tvDate;
ImageView row_img;
public posts(View v) {
super(v);
tvTittle = (TextView) v.findViewById(R.id.row_cmnt);
tvPostId = (TextView) v.findViewById(R.id.row_postid);
tvUseId = (TextView) v.findViewById(R.id.row_userid);
tvName = (TextView) v.findViewById(R.id.row_name);
tvCat = (TextView) v.findViewById(R.id.row_cat);
tvDate = (TextView) v.findViewById(R.id.row_date);
row_img = (ImageView) v.findViewById(R.id.row_img);

v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

Intent intent;
TextView text = (TextView) v.findViewById(R.id.row_postid);
String lst_txt = text.getText().toString().trim();
intent = new Intent(v.getContext(), PostView.class);
intent.putExtra("post_id", lst_txt);
v.getContext().startActivity(intent);
}
});
}
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {

final posts holder = (posts) viewHolder;
Post post = listData.get(position);
rpostid = post.getPost_id();
ruserid = post.getUser_id();
rname = post.getUser_name();
rcat = post.getPost_cat();
rdate = post.getPost_time();
rtittle = post.getPost_title();
holder.tvPostId.setText(rpostid);
holder.tvUseId.setText(ruserid);
holder.tvName.setText(rname);
holder.tvCat.setText(rcat);
holder.tvDate.setText(rdate);
holder.tvTittle.setText(rtittle);
urlThumnail = post.getImg_link();
Log.d("qwerty","link of image lru: "+ urlThumnail);
if (urlThumnail != null){
imageLoader.get(urlThumnail, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
holder.row_img.setImageBitmap(response.getBitmap());
Log.d("qwerty","post attached 2");
}

@Override
public void onErrorResponse(VolleyError error) {
Log.d("qwerty","post attached 3");
}
});
}
}

@Override
public int getItemCount() {
return (null != listData ? listData.size() : 0);
}


}

And here is the code by which all the new posts will be fetched from the DB:

private ArrayList<Post> parseJSONResponse(JSONObject response) {
if (response == null || response.length() == 0) {
} else {
try {
JSONArray jsonArray = response.getJSONArray("post");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObjectPOST = jsonArray.getJSONObject(i);
String post_id = jsonObjectPOST.getString(Key_post_id);
String user_id = jsonObjectPOST.getString(Key_user_id);
String user_name = jsonObjectPOST.getString(Key_user_name);
String img_link = jsonObjectPOST.getString(Key_img_link);
String post_title = jsonObjectPOST.getString(Key_post_title);
String post_desc = jsonObjectPOST.getString(Key_post_desc);
String post_exp_date = jsonObjectPOST.getString(Key_post_exp);
String post_cat = jsonObjectPOST.getString(Key_post_cat);
String post_time = jsonObjectPOST.getString(Key_post_time);
Log.d("response",post_id+" "+user_id+" "+user_name+" "+img_link);
Post postitem = new Post();
postitem.setPost_id(post_id);
postitem.setUser_id(user_id);
postitem.setUser_name(user_name);
postitem.setImg_link(img_link);
postitem.setPost_title(post_title);
postitem.setDesc(post_desc);
postitem.setEXP(post_exp_date);
postitem.setPost_cat(post_cat);
postitem.setPost_time(post_time);

if(jsonObjectPOST.has(Key_post_id) &&
jsonObjectPOST.has(Key_user_id) &&
jsonObjectPOST.has(Key_user_name) &&
jsonObjectPOST.has(Key_img_link) &&
jsonObjectPOST.has(Key_post_title) &&
jsonObjectPOST.has(Key_post_desc) &&
jsonObjectPOST.has(Key_post_exp) &&
jsonObjectPOST.has(Key_post_cat) &&
jsonObjectPOST.has(Key_post_time)){

if(!jsonObjectPOST.isNull(Key_post_id) &&
!jsonObjectPOST.isNull(Key_user_id) &&
!jsonObjectPOST.isNull(Key_user_name) &&
!jsonObjectPOST.isNull(Key_img_link) &&
!jsonObjectPOST.isNull(Key_post_title) &&
!jsonObjectPOST.isNull(Key_post_desc) &&
!jsonObjectPOST.isNull(Key_post_exp) &&
!jsonObjectPOST.isNull(Key_post_cat) &&
!jsonObjectPOST.isNull(Key_post_time)){

handler.addPost(postitem);
new CountDownTimer(2000, 1000) {
public void onTick(long millisUntilFinished) {}
public void onFinish() {
postList = handler.getAllPost();
t = Integer.parseInt(postList.get(1).getPost_id().toString().trim());
Log.d("Check", "postid: "+t);
Hpbar.setVisibility(View.INVISIBLE);
Log.d("jsonCount", String.valueOf(postList));
String AdapterData = String.valueOf(postList);
if(AdapterData.equals("[]")){
Htvnopostfound.setVisibility(View.VISIBLE);
}else{
adapter = new PostAdapter(postList);
listView.setAdapter(adapter);
}
}
}.start();

}else{

}

}else{

}
}

} catch (JSONException e) {
e.printStackTrace();
}
}
return postList;
}

private ArrayList<Post> swipeJSONResponse(JSONObject response) {
if (response == null || response.length() == 0) {
} else {
try {
JSONArray jsonArray = response.getJSONArray("post");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObjectPOST = jsonArray.getJSONObject(i);
String post_id = jsonObjectPOST.getString(Key_post_id);
String user_id = jsonObjectPOST.getString(Key_user_id);
String user_name = jsonObjectPOST.getString(Key_user_name);
String img_link = jsonObjectPOST.getString(Key_img_link);
String post_title = jsonObjectPOST.getString(Key_post_title);
String post_desc = jsonObjectPOST.getString(Key_post_desc);
String post_exp_date = jsonObjectPOST.getString(Key_post_exp);
String post_cat = jsonObjectPOST.getString(Key_post_cat);
String post_time = jsonObjectPOST.getString(Key_post_time);
Post postitem = new Post();
postitem.setPost_id(post_id);
postitem.setUser_id(user_id);
postitem.setUser_name(user_name);
postitem.setImg_link(img_link);
postitem.setPost_title(post_title);
postitem.setDesc(post_desc);
postitem.setEXP(post_exp_date);
postitem.setPost_cat(post_cat);
postitem.setPost_time(post_time);

if(jsonObjectPOST.has(Key_post_id) &&
jsonObjectPOST.has(Key_user_id) &&
jsonObjectPOST.has(Key_user_name) &&
jsonObjectPOST.has(Key_img_link) &&
jsonObjectPOST.has(Key_post_title) &&
jsonObjectPOST.has(Key_post_desc) &&
jsonObjectPOST.has(Key_post_exp) &&
jsonObjectPOST.has(Key_post_cat) &&
jsonObjectPOST.has(Key_post_time)){

if(!jsonObjectPOST.isNull(Key_post_id) &&
!jsonObjectPOST.isNull(Key_user_id) &&
!jsonObjectPOST.isNull(Key_user_name) &&
!jsonObjectPOST.isNull(Key_img_link) &&
!jsonObjectPOST.isNull(Key_post_title) &&
!jsonObjectPOST.isNull(Key_post_desc) &&
!jsonObjectPOST.isNull(Key_post_exp) &&
!jsonObjectPOST.isNull(Key_post_cat) &&
!jsonObjectPOST.isNull(Key_post_time)){

handler.addPost(postitem);
new CountDownTimer(2000, 1000) {
public void onTick(long millisUntilFinished) {}
public void onFinish() {
postList = handler.getAllNewPost(t);
adapter.notifyItemInserted(1);
Log.d("check","post_id "+t+" hello");
/*adapter = new PostAdapter(postList);
listView.setAdapter(adapter);
Log.d("check","post_id "+t+" hello 2");*/
Log.d("check","post_id "+t+" hello 2");
Hpbar.setVisibility(View.INVISIBLE);
swipeRefreshLayout.setRefreshing(false);
}
}.start();

}else{

}

}else{

}
}

} catch (JSONException e) {
e.printStackTrace();
}
}
return postList;
}


On startup
parseJSONResponse
is used and for
swipeToRefresh
swipeJSONResponse
is used. In
parseJSONResponse
, the last displayed post's id is stored in
int t
and then this
int t
is passed to
swipeJSONResponse
to get the new post.

But after refreshing, new data will not show in the list. SO, please tell me how to do so. I've read a few articles where
add
is used, as such:

listview.add(0, item);


But I don't know how to implement this with multiple rows of data at same time. Thanks in advance.

Answer

The correct way to update data in a listView should be:

1) create an update data method in your adapter. In your case could be like this:

public updateData(ArrayList<Post> postList) {
  this.listData=postList;
  notifyDataSetChanged();
}

or, if you want just append data on the top:

public addNewDataOnTop(ArrayList<Post> postList) {
  this.listData.addAll(0,postList);
  notifyDataSetChanged();
}

2) When you have new data to add, do not create a new adapter but just update the data

  • When you create the listView at the beginning you set the empty adapter:

     adapter = new PostAdapter(new ArrayList());
     listView.setAdapter(adapter);
    
  • When you receive the new data, you just update the adapter:

     adapter.addNewDataOnTop(postList);
    

I hope it helped