5

I'm trying to add some date on scroll top in a recyclerview. it is work, except the scroll, it mess everything up when some new data is added.

I saw this topics:

Link 1

Link 2

but none of them solved my problem.

maybe someone can help me with this...

I get some data using volley, like so:

try { //Getting json json = array.getJSONObject(i); //Adding data to the object PostObj.setImageUrl(json.getString(Config.TAG_PPIC)); ... } catch (JSONException e) { e.printStackTrace(); } //Adding object to the list listLf.add(0, PostObj); //0, postobj } //Notifying the adapter that data has been added or changed //adapter.notifyDataSetChanged(); the scroll will jump to position 0 adapter.notifyItemRangeChanged(0, adapter.getItemCount()); // still not working } 

I tried to add adapter.notifyItemRangeChanged(0, adapter.getItemCount()); but still the same thing.

also I tried:

// Save state private Parcelable recyclerViewState; recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState(); // Restore state recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState); 

and it doesn't work too. maybe I place it in the wrong place or something...

I want some suggestions what I'm doing wrong and how can I get the new data, notify the adapter without mess the scroll position?


edit---------------------------------- full class:

public class Comments extends BaseActivity { private List<LfGetSet> listLf; //Creating Views private RecyclerView recyclerView; private RecyclerView.LayoutManager layoutManager; private RecyclerView.Adapter adapter; //Volley Request Queue private RequestQueue requestQueue; private String requestCount = "0"; private String lastrequestCount = "0"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewGroup content = (ViewGroup) findViewById(R.id.content_frame); getLayoutInflater().inflate(R.layout.activity_comments, content, true); //Initializing Views recyclerView = (RecyclerView) findViewById(R.id.recyclerViewLf); recyclerView.setHasFixedSize(true); //layoutManager = new LinearLayoutManager(this); final LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setStackFromEnd(true); recyclerView.setLayoutManager(layoutManager); //Initializing our list listLf = new ArrayList<>(); requestQueue = Volley.newRequestQueue(this); //Calling method to get data to fetch data getData(); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (isLastItemDisplaying(recyclerView)) { getData(); } } }); //initializing our adapter adapter = new LfAdapter(listLf, this); //Adding adapter to recyclerview recyclerView.setAdapter(adapter); } private JsonArrayRequest getDataFromServer(String requestCount) { ... return jsonArrayRequest; } //This method will get data from the web api private void getData() { //Adding the method to the queue by calling the method getDataFromServer requestQueue.add(getDataFromServer(requestCount)); lastrequestCount = requestCount; //Incrementing the request counter requestCount++; } //This method will parse json data private void parseData(JSONArray array) { for (int i = 0; i < array.length(); i++) { //Creating the object LfGetSet PostObj = new LfGetSet(); JSONObject json = null; try { //Getting json json = array.getJSONObject(i); //Adding data to the object PostObj.setImageUrl(json.getString(Config.TAG_PPIC)); ... } catch (JSONException e) { e.printStackTrace(); } //Adding object to the list listLf.add(0, PostObj); //0, postobj } //Notifying the adapter that data has been added or changed adapter.notifyDataSetChanged(); } //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()).findFirstVisibleItemPosition(); if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == 1 && lastrequestCount != requestCount && requestCount != "0") return true; } return false; } } 
2
  • 1
    When you add an item you should use the notifyItemInserted method. Commented Mar 21, 2017 at 0:05
  • I tried adapter.notifyItemInserted(0); , adapter.notifyItemInserted(adapter.getItemCount()) and none of them work. they seems to group all posts in the first position and show them when scroll bottom and top again... Did I do something wrong? @RobCo Commented Mar 21, 2017 at 0:39

1 Answer 1

1

You can try this approach where you add a new item to the list as per normal and then update the data in the array and put the new one at the top.

 // Add a new item the usual way so it goes at the bottom int x = 0; // Create a new Data list. New item goes 1st // Create a Loop myList.remove(x); // Remove item from the array at position MyList myList = new MyList(); myList.add(x, theData); // Add data to array at position // Now that new data has been inserted to the Array at position X update the List item at that same Position. I usually do this in the Background. Handler handler = new Handler(); final int finalX = x; final Runnable r = new Runnable() { public void run() { adapter.notifyItemChanged(finalX); // Notify Adapter that the Items data has changed and Update } }; handler.post(r); x++; 

Code that reads updated data from the DB and then updates List items on the fly with that new data. But in your case you need to add 1 new item and update the List with the new items data at position 0 in the array and on the List. Old items get their position shifted by 1.

public void updateStocks() { System.out.println("Updating"); int rec = db.getRecordsCount() - 1; List<Records> record = db.getAllRecords(); int x = 0; for (Records cn : record) { stocksList.remove(x); Livestocks stocks = new Livestocks(); stocks.setID(cn.getID()); stocks.setName(cn.getName()); stocks.setTicker(cn.getTicker()); stocks.setPrice(cn.getPrice()); stocks.setOpen(cn.getOpen()); stocks.setChange(cn.getChange()); stocks.setPchange(cn.getPchange()); stocks.setDhigh(cn.getDhigh()); stocks.setDlow(cn.getDlow()); stocks.setYhigh(cn.getYhigh()); stocks.setYlow(cn.getYlow()); stocks.setVol(cn.getVol()); stocks.setShares(cn.getShares()); stocks.setIown(cn.getIown()); stocks.setMcap(cn.getMcap()); stocks.setStatus(cn.getStatus()); stocks.setExchange(cn.getExchange()); stocksList.add(x, stocks); Handler handler = new Handler(); final int finalX = x; final Runnable r = new Runnable() { public void run() { adapter.notifyItemChanged(finalX); } }; handler.post(r); x++; if (rec == x) { //do nothing } } } 
Sign up to request clarification or add additional context in comments.

5 Comments

I'll try your solution, thank you! finalX is the number of data I'm inserting isn't it? the i number in for?
@Gabriela Dias -- No im copying the value of x to a final integer so it can be read within the handler to update the data of the List item as you see it on screen at the same position as the arrays data -- Array data and List Items have the same postions starting from Zero onwards -- x and finalX have the same value
@Gabriela Dias -- To explain further, The steps of the code i provided is usually for updating a List item on the fly without having to refresh the whole list. However because you are adding 1 and want it to be on top you will need add 1 the usually way so total array items matches List items No, and lastly you update on the fly but you put the new 1st. You may notice a slight shift of 1 items data
oh, I see! I'll try your solution. it is clever. thanks!
@Gabriela Dias -- it will work Ok. After you add 1 new item the usually way all you are doing is shifting old data to a + 1 position on the list and update on the fly as you require the new item to be the 1st on the list. I will add the code i use for a Stocks App i use but all it does is just reads updated data from the DB and updates the list on the fly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.