Search code examples
javaandroidweb-servicesandroid-recyclerviewcustom-adapter

How to add new feed to recycleview at same time without scroll or refresh the view?


I have an activity in which I have used Recycle View to show all items as a list. On same activity I have given functionality to add new item. Everything is working fine. Items are adding in my database and its showing in list. I have added pagination on Recycle View it is also working fine. What I want that when user add new item at the same time when new data added to database but it is not updating in list. When user press back and again come on activity after that it is showing in list. I want to add add new item at same time without scroll the list or without go back.

TimelineActivity.java

public class TimelineActivity extends AppCompatActivity implements RecyclerView.OnScrollChangeListener {

                private static final String TAG = MainActivity.class.getSimpleName();
                private RecyclerView listView;
                private RecyclerView.LayoutManager layoutManager;
                private RecyclerView.Adapter adapter;
                private TimeLineListAdapter listAdapter;
                private List<TimeLineItem> timeLineItems;
                private int requestCount = 1;
                private ProgressDialog pDialog;

                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_timeline);
                    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

                    listView = (RecyclerView) findViewById(R.id.list);
                    listView.setHasFixedSize(true);
                    layoutManager = new LinearLayoutManager(this);
                    listView.setLayoutManager(layoutManager);
                    btnPost = (Button) findViewById(R.id.btnPost);

                    //Adding an scroll change listener to recyclerview
                    listView.setOnScrollChangeListener(this);

                    // Progress dialog
                    pDialog = new ProgressDialog(this);
                    pDialog.setCancelable(false);

                    cd = new ConnectionDetector(this);
                    isInternetPresent = cd.isConnectingToInternet();

                    db = new SQLiteHandler(this);

                    // session manager
                    session = new SessionManager(this);

                    /*pref = getApplicationContext().getSharedPreferences("MayahudiPref", 0);
                    editor = pref.edit();*/

                    buttonClickEvent();

                    // Fetching user details from sqlite
                    HashMap<String, String> user = db.getUserDetails();
                    id = user.get("id");
                    token = user.get("token");


                    getData();

                    timeLineItems = new ArrayList<>();

                    adapter = new TimeLineListAdapter(timeLineItems, this);
                    listView.setAdapter(adapter);


                    Timer autoRefresh;
                    autoRefresh=new Timer();
                    autoRefresh.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            runOnUiThread(new Runnable() {
                                public void run() {
                                    getTimeLineData(token, "1");
                                }
                            });
                        }
                    }, 0, 2000);
                }

                public void getTimeLineData(final String token, final String page) {


                    String tag_string_req = "req_register";
                    // making fresh volley request and getting json
                    StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.timeline, new Response.Listener<String>() {

                        @Override
                        public void onResponse(String response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            if (response != null) {
                                try {
                                    JSONObject jObj = new JSONObject(response);
                                    boolean error = jObj.getBoolean("status");
                                    String message = jObj.getString("message");
                                    if (error) {
                                        totalPages = jObj.getInt("totalPages");
                                        pageCount = jObj.getInt("page");

                                        int limit = jObj.getInt("limit");
                                        parseJsonFeed(response);
                                    }

                                } catch (Exception e) {

                                }

                            }
                        }
                    }, new Response.ErrorListener() {

                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    }) {

                        @Override
                        protected Map<String, String> getParams() {
                            // Posting params to register url
                            Map<String, String> params = new HashMap<String, String>();
                            params.put("my_token", token);
                            params.put("page", page);
                            params.put("limit", "5");

                            return params;
                        }
                    };

                    // Adding request to request queue
                    AppController.getInstance().addToRequestQueue(strReq, tag_string_req);

                }

                private void parseJsonFeed(String response) {
                    try {
                        JSONObject jsonObj = new JSONObject(response);
                        JSONArray feedArray = jsonObj.getJSONArray("data");

                        for (int i = 0; i < feedArray.length(); i++) {
                            JSONObject feedObj = (JSONObject) feedArray.get(i);

                            TimeLineItem item = new TimeLineItem();
                            item.setId(feedObj.getInt("id"));
                            item.setName(feedObj.getString("name"));
                            item.setLname(feedObj.getString("lname"));

                            // Image might be null sometimes
                            String image = feedObj.isNull("image") ? null : feedObj
                                    .getString("image");

                            if (image.equals("")) {
                                item.setImge(image);
                            } else {
                                item.setImge(AppConfig.storyPic + image);
                            }

                            item.setStatus(feedObj.getString("story_text"));
                            item.setProfilePic(AppConfig.profilePic + feedObj.getString("profile_pic"));
                            item.setTimeStamp(feedObj.getString("time_stamp"));
                            item.setIsLike(feedObj.getInt("is_like"));
                            item.setTotalLikes(feedObj.getString("total_likes"));
                            item.setTotalComment(feedObj.getString("total_comments"));

                            /*// url might be null sometimes
                            String feedUrl = feedObj.isNull("url") ? null : feedObj
                                    .getString("url");
                            item.setUrl(feedUrl);*/

                            timeLineItems.add(item);
                        }

                        // notify data changes to list adapater
                        adapter.notifyDataSetChanged();


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

                //This method will get data from the web API
                private void getData() {
                    //Adding the method to the queue by calling the method getDataFromServer
                    getTimeLineData(token, String.valueOf(requestCount));
                    //Incrementing the request counter
                    requestCount++;
                }

                //This method would check that the recyclerview scroll has reached the bottom or not
                private boolean isLastItemDisplaying(RecyclerView recyclerView) {
                    if (recyclerView.getAdapter().getItemCount() != 0) {
                        int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
                        if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)

                            return true;
                    }
                    return false;
                }

                @Override
                public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                    //Ifscrolled at last then
                    if (isLastItemDisplaying(listView)) {
                        //Calling the method getdata again
                        getData();
                    }
                }

                public void buttonClickEvent() {

                    btnPost.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            if (isInternetPresent) {

                                String text = txtStatusBox.getText().toString().trim();

                                if (!text.isEmpty()) {
                                    if (thumbnail != null) {

                                        String image = getStringImage(thumbnail);

                                        JSONObject student2 = new JSONObject();
                                        try {
                                            student2.put("size", "1000");
                                            student2.put("type", "image/jpeg");
                                            student2.put("data", image);
                                        } catch (JSONException e) {
                                            e.printStackTrace();
                                        }
                                        addStory(text, token, String.valueOf(student2));
                                    } else {
                                        addStory(text, token, "");
                                    }

                                } else {
                                    Toast.makeText(TimelineActivity.this, "Please add some text or image.", Toast.LENGTH_SHORT).show();
                                }

                            } else {
                                final SweetAlertDialog alert = new SweetAlertDialog(TimelineActivity.this, SweetAlertDialog.WARNING_TYPE);
                                alert.setTitleText("No Internet");
                                alert.setContentText("No connectivity. Please check your internet.");
                                alert.show();
                            }
                        }
                    });

                    btnCancel.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            txtStatusBox.setText("");
                            imgImageUpload.setImageBitmap(null);
                            imgImageUpload.setBackgroundResource(R.drawable.image);
                            Toast.makeText(TimelineActivity.this, message, Toast.LENGTH_SHORT).show();
                            slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
                        }
                    });

                    imgImageUpload.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            selectImage();
                        }
                    });

                    /*fab.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {

                            myDialogFragment.show(getFragmentManager(), "MyDialogFragment");

                            //Toast.makeText(TimelineActivity.this, "Floating Button", Toast.LENGTH_SHORT).show();
                        }
                    });*/

                }

                private void addStory(final String story_text, final String token, final String image) {
                    // Tag used to cancel the request
                    String tag_string_req = "req_register";

                    pDialog.setMessage("Please wait ...");
                    showDialog();

                    StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.addStory, new Response.Listener<String>() {

                        @Override
                        public void onResponse(String response) {
                            hideDialog();

                            try {
                                JSONObject jObj = new JSONObject(response);
                                boolean error = jObj.getBoolean("status");
                                message = jObj.getString("message");
                                if (error) {
                                    txtStatusBox.setText("");
                                    imgImageUpload.setImageBitmap(null);
                                    imgImageUpload.setBackgroundResource(R.drawable.image);
                                    Toast.makeText(TimelineActivity.this, message, Toast.LENGTH_SHORT).show();
                                    slidingUpPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);

                                } else {

                                    // Error occurred in registration. Get the error
                                    // message
                                    String errorMsg = jObj.getString("message");
                                    Toast.makeText(TimelineActivity.this, errorMsg, Toast.LENGTH_LONG).show();
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                        }
                    }, new Response.ErrorListener() {

                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Toast.makeText(TimelineActivity.this, "Oops something went wrong...", Toast.LENGTH_LONG).show();
                            hideDialog();
                        }
                    }) {

                        @Override
                        protected Map<String
                                , String> getParams() {
                            // Posting params to register url
                            Map<String, String> params = new HashMap<String, String>();
                            params.put("my_token", token);
                            params.put("story_text", story_text);
                            params.put("image", image);

                            return params;
                        }

                    };

                    // Adding request to request queue
                    AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
                }

                private void showDialog() {
                    if (!pDialog.isShowing())
                        pDialog.show();
                }

                private void hideDialog() {
                    if (pDialog.isShowing())
                        pDialog.dismiss();
                }
            }

TimeLineListAdapter.java

public class TimeLineListAdapter extends RecyclerView.Adapter<TimeLineListAdapter.ViewHolder> {
    private List<TimeLineItem> timeLineItems;
    String message, storyId, token;
    private Context context;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();

    public TimeLineListAdapter(List<TimeLineItem> timeLineItems, Context context) {
        super();
        this.context = context;
        this.timeLineItems = timeLineItems;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.timeline_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(v);
        return viewHolder;
    }

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

        //Getting the particular item from the list
        TimeLineItem item =  timeLineItems.get(position);

        if (item.getTotalLikes().equals("0")){
            holder.txtLike.setText("");
        }else {
            holder.txtLike.setText(item.getTotalLikes());
        }

        if (item.getTotalComment().equals("0")){
            holder.txtComment.setText("");
        }else {
            holder.txtComment.setText("("+item.getTotalComment()+")");
        }

        if (item.getIsLike() == 0){

        }else {
            holder.imageLike.setImageBitmap(null);
            holder.imageLike.setBackgroundResource(R.drawable.islike);
            holder.txtLike.setTextColor(Color.parseColor("#3498db"));
        }

        holder.name.setText(item.getName() + " " + item.getLname());


        /*Long.parseLong(item.getTimeStamp()),
                System.currentTimeMillis(), DateUtils.SECOND_IN_MILLIS);*/
        holder.timestamp.setText(item.getTimeStamp());

        // Chcek for empty status message
        if (!TextUtils.isEmpty(item.getStatus())) {
            holder.statusMsg.setText(item.getStatus());
            holder.statusMsg.setVisibility(View.VISIBLE);
        } else {
            // status is empty, remove from view
            holder.statusMsg.setVisibility(View.GONE);
        }

        // Checking for null feed url
        if (item.getUrl() != null) {
            holder.url.setText(Html.fromHtml("<a href=\"" + item.getUrl() + "\">"
                    + item.getUrl() + "</a> "));

            // Making url clickable
            holder.url.setMovementMethod(LinkMovementMethod.getInstance());
            holder.url.setVisibility(View.VISIBLE);
        } else {
            // url is null, remove from the view
            holder.url.setVisibility(View.GONE);
        }

        // user profile pic
        holder.profilePic.setImageUrl(item.getProfilePic(), imageLoader);

        // Feed image
        if (item.getImge() != null) {
            holder.feedImageView.setImageUrl(item.getImge(), imageLoader);
            holder.feedImageView.setVisibility(View.VISIBLE);
            holder.feedImageView
                    .setResponseObserver(new TimeLineImageView.ResponseObserver() {
                        @Override
                        public void onError() {
                        }

                        @Override
                        public void onSuccess() {
                        }
                    });
        } else {
            holder.feedImageView.setVisibility(View.GONE);
        }

    }

    @Override
    public int getItemCount() {
        return timeLineItems.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        TextView name, timestamp, statusMsg, url, txtLike, txtComment, txtCommentLabel;
        NetworkImageView profilePic;
        TimeLineImageView feedImageView;
        ImageView imageLike;

        //Initializing Views
        public ViewHolder(View itemView) {
            super(itemView);
            name = (TextView) itemView.findViewById(R.id.name);
            timestamp = (TextView) itemView.findViewById(R.id.timestamp);
            statusMsg = (TextView) itemView.findViewById(R.id.txtStatusMsg);
            url = (TextView) itemView.findViewById(R.id.txtUrl);
            profilePic = (NetworkImageView) itemView.findViewById(R.id.profilePic);
            feedImageView = (TimeLineImageView) itemView.findViewById(R.id.feedImage1);
            imageLike = (ImageView) itemView.findViewById(R.id.imgLike);
            txtLike = (TextView) itemView.findViewById(R.id.txtLike);
            txtComment = (TextView) itemView.findViewById(R.id.txtComment);
            txtCommentLabel = (TextView) itemView.findViewById(R.id.txtCommentLabel);
        }
    }

Solution

  • You have to notifiy dataset changed on listview when new feed is added so there are two things you can do :

    1. Create a new TimeLineItem item when new feed is entered and add new item to it like this :

    `

    item.setStatus("New Status");
     item.setProfilePic("New Profile Pic");
     item.setTimeStamp("New TimeStamp");
     item.setIsLike("True");
     item.setTotalLikes("1000");
     item.setTotalComment("2");
    

    `

    and then use timeLineItems.add(item) to add new item to ArrayList and call adapter.notifyDataSetChanged(); to get it in view . 2. Again create volley request and it will do it automatically but this is slower then above example. If you have any query please ask .