ScrollToPosition for Lazy Loading RecyclerView










0















I'm trying to build a simple activity for messaging in android.




  • I have a RecyclerView that list the messages and I set a ScrollListener on it.

  • When the firstVisibleItem is the third of the list (RecyclerView stack from end), I will make a call to load other elements.

  • I add this element to my array and I set a new adapter on my RecyclerView for the update.

  • When I set the new adapter, the list starts one more time from the last message.

  • So far I have tried to use scrollToPosition to go to the message where the user was before scrollListener was triggered, but still not work at all because the lastVisibleItem become 1 every time.



Is there a way to maintain the last firstVisible element and set this element as the top element after reset the Adapter?



This is the onCreateMethod.



@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);

lastOffset = 0;
requestSize = 20;

loadMessage()

mAdapter = new ChatAdapter(this,mess);
llm = new LinearLayoutManager(this);
llm.setStackFromEnd(true);
mex_list.setLayoutManager(llm);
mex_list.setAdapter(mAdapter);
mex_list.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
int lastVisible = llm.findLastVisibleItemPosition();
int firstVisible = llm.findFirstVisibleItemPosition();
lastFirstVisibleItem = firstVisibleItem; //lastFirstVisibleItem is a global variable
if(firstVisible <= 3)
if(!loading)
loading = true;
loadMessage();


Log.d("Test Scroll", "LAST: "+ lastVisible+" FIRST: "+firstVisible);

);


This is where the laodMessage() result was managed.



 public void manageResult(Object pr, int caller) 
if(caller == MESSAGES_REQ)
if(mess == null)
mess = new ArrayList<>();
ArrayList<Message> tail = (ArrayList<Message>) pr;

if(tail != null && tail.size() > 0)
lastOffset += tail.size();
mess.addAll(tail);
mAdapter = new ChatAdapter(ctx, mess);
mex_list.setAdapter(mAdapter);


llm.scrollToPosition(lastFirstVisibleItem);//lastFirstVisibleItem became always 1
spinner.setVisibility(View.GONE);
printEmpMex(View.GONE);
mex_list.setVisibility(View.VISIBLE);
loading = false;




This is the ChatAdapter.



public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> 

private ArrayList<Message> listOfMessages;
private static Context ctx;

private static final int SENT = 100;
private static final int RECIVED = 200;

public static class ViewHolder extends RecyclerView.ViewHolder
public TextView text;
public TextView hour;


public ViewHolder(View v)
super(v);
text = (TextView) v.findViewById(R.id.text_body);
hour = (TextView) v.findViewById(R.id.time);


void bind(Message m)
text.setText(m.getBody());
hour.setText(formatDateAndHour(m.getDate()));



public ChatAdapter(Context ctx, ArrayList<Message> m)
listOfMessages = m;
this.ctx = ctx;


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType)

View view;
if (viewType == SENT)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_sent, parent, false);
return new ViewHolder(view);


else if (viewType == RECIVED)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_recived, parent, false);
return new ViewHolder(view);


return null;


@Override
public void onBindViewHolder(ViewHolder holder, int position)
Message mex = listOfMessages.get(position);
holder.bind(mex);


@Override
public int getItemCount()
return listOfMessages.size();


@Override
public int getItemViewType(int position)
Message m = listOfMessages.get(position);
if(m.getSender().getIdUser().equals(loggedUser.getIdUser()))
return SENT;
else
return RECIVED;



I really don't know how to make it work.
Every approach is welcome.



Thanks in advance.










share|improve this question
























  • Do you control ChatAdapter? Could you post its source code?

    – Ben P.
    Nov 12 '18 at 15:56











  • I have posted the code

    – Ferdinando D'avino
    Nov 12 '18 at 16:17












  • this link may help you stackoverflow.com/questions/31000964/…

    – Zahoor Saleem
    Nov 12 '18 at 16:31















0















I'm trying to build a simple activity for messaging in android.




  • I have a RecyclerView that list the messages and I set a ScrollListener on it.

  • When the firstVisibleItem is the third of the list (RecyclerView stack from end), I will make a call to load other elements.

  • I add this element to my array and I set a new adapter on my RecyclerView for the update.

  • When I set the new adapter, the list starts one more time from the last message.

  • So far I have tried to use scrollToPosition to go to the message where the user was before scrollListener was triggered, but still not work at all because the lastVisibleItem become 1 every time.



Is there a way to maintain the last firstVisible element and set this element as the top element after reset the Adapter?



This is the onCreateMethod.



@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);

lastOffset = 0;
requestSize = 20;

loadMessage()

mAdapter = new ChatAdapter(this,mess);
llm = new LinearLayoutManager(this);
llm.setStackFromEnd(true);
mex_list.setLayoutManager(llm);
mex_list.setAdapter(mAdapter);
mex_list.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
int lastVisible = llm.findLastVisibleItemPosition();
int firstVisible = llm.findFirstVisibleItemPosition();
lastFirstVisibleItem = firstVisibleItem; //lastFirstVisibleItem is a global variable
if(firstVisible <= 3)
if(!loading)
loading = true;
loadMessage();


Log.d("Test Scroll", "LAST: "+ lastVisible+" FIRST: "+firstVisible);

);


This is where the laodMessage() result was managed.



 public void manageResult(Object pr, int caller) 
if(caller == MESSAGES_REQ)
if(mess == null)
mess = new ArrayList<>();
ArrayList<Message> tail = (ArrayList<Message>) pr;

if(tail != null && tail.size() > 0)
lastOffset += tail.size();
mess.addAll(tail);
mAdapter = new ChatAdapter(ctx, mess);
mex_list.setAdapter(mAdapter);


llm.scrollToPosition(lastFirstVisibleItem);//lastFirstVisibleItem became always 1
spinner.setVisibility(View.GONE);
printEmpMex(View.GONE);
mex_list.setVisibility(View.VISIBLE);
loading = false;




This is the ChatAdapter.



public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> 

private ArrayList<Message> listOfMessages;
private static Context ctx;

private static final int SENT = 100;
private static final int RECIVED = 200;

public static class ViewHolder extends RecyclerView.ViewHolder
public TextView text;
public TextView hour;


public ViewHolder(View v)
super(v);
text = (TextView) v.findViewById(R.id.text_body);
hour = (TextView) v.findViewById(R.id.time);


void bind(Message m)
text.setText(m.getBody());
hour.setText(formatDateAndHour(m.getDate()));



public ChatAdapter(Context ctx, ArrayList<Message> m)
listOfMessages = m;
this.ctx = ctx;


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType)

View view;
if (viewType == SENT)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_sent, parent, false);
return new ViewHolder(view);


else if (viewType == RECIVED)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_recived, parent, false);
return new ViewHolder(view);


return null;


@Override
public void onBindViewHolder(ViewHolder holder, int position)
Message mex = listOfMessages.get(position);
holder.bind(mex);


@Override
public int getItemCount()
return listOfMessages.size();


@Override
public int getItemViewType(int position)
Message m = listOfMessages.get(position);
if(m.getSender().getIdUser().equals(loggedUser.getIdUser()))
return SENT;
else
return RECIVED;



I really don't know how to make it work.
Every approach is welcome.



Thanks in advance.










share|improve this question
























  • Do you control ChatAdapter? Could you post its source code?

    – Ben P.
    Nov 12 '18 at 15:56











  • I have posted the code

    – Ferdinando D'avino
    Nov 12 '18 at 16:17












  • this link may help you stackoverflow.com/questions/31000964/…

    – Zahoor Saleem
    Nov 12 '18 at 16:31













0












0








0








I'm trying to build a simple activity for messaging in android.




  • I have a RecyclerView that list the messages and I set a ScrollListener on it.

  • When the firstVisibleItem is the third of the list (RecyclerView stack from end), I will make a call to load other elements.

  • I add this element to my array and I set a new adapter on my RecyclerView for the update.

  • When I set the new adapter, the list starts one more time from the last message.

  • So far I have tried to use scrollToPosition to go to the message where the user was before scrollListener was triggered, but still not work at all because the lastVisibleItem become 1 every time.



Is there a way to maintain the last firstVisible element and set this element as the top element after reset the Adapter?



This is the onCreateMethod.



@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);

lastOffset = 0;
requestSize = 20;

loadMessage()

mAdapter = new ChatAdapter(this,mess);
llm = new LinearLayoutManager(this);
llm.setStackFromEnd(true);
mex_list.setLayoutManager(llm);
mex_list.setAdapter(mAdapter);
mex_list.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
int lastVisible = llm.findLastVisibleItemPosition();
int firstVisible = llm.findFirstVisibleItemPosition();
lastFirstVisibleItem = firstVisibleItem; //lastFirstVisibleItem is a global variable
if(firstVisible <= 3)
if(!loading)
loading = true;
loadMessage();


Log.d("Test Scroll", "LAST: "+ lastVisible+" FIRST: "+firstVisible);

);


This is where the laodMessage() result was managed.



 public void manageResult(Object pr, int caller) 
if(caller == MESSAGES_REQ)
if(mess == null)
mess = new ArrayList<>();
ArrayList<Message> tail = (ArrayList<Message>) pr;

if(tail != null && tail.size() > 0)
lastOffset += tail.size();
mess.addAll(tail);
mAdapter = new ChatAdapter(ctx, mess);
mex_list.setAdapter(mAdapter);


llm.scrollToPosition(lastFirstVisibleItem);//lastFirstVisibleItem became always 1
spinner.setVisibility(View.GONE);
printEmpMex(View.GONE);
mex_list.setVisibility(View.VISIBLE);
loading = false;




This is the ChatAdapter.



public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> 

private ArrayList<Message> listOfMessages;
private static Context ctx;

private static final int SENT = 100;
private static final int RECIVED = 200;

public static class ViewHolder extends RecyclerView.ViewHolder
public TextView text;
public TextView hour;


public ViewHolder(View v)
super(v);
text = (TextView) v.findViewById(R.id.text_body);
hour = (TextView) v.findViewById(R.id.time);


void bind(Message m)
text.setText(m.getBody());
hour.setText(formatDateAndHour(m.getDate()));



public ChatAdapter(Context ctx, ArrayList<Message> m)
listOfMessages = m;
this.ctx = ctx;


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType)

View view;
if (viewType == SENT)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_sent, parent, false);
return new ViewHolder(view);


else if (viewType == RECIVED)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_recived, parent, false);
return new ViewHolder(view);


return null;


@Override
public void onBindViewHolder(ViewHolder holder, int position)
Message mex = listOfMessages.get(position);
holder.bind(mex);


@Override
public int getItemCount()
return listOfMessages.size();


@Override
public int getItemViewType(int position)
Message m = listOfMessages.get(position);
if(m.getSender().getIdUser().equals(loggedUser.getIdUser()))
return SENT;
else
return RECIVED;



I really don't know how to make it work.
Every approach is welcome.



Thanks in advance.










share|improve this question
















I'm trying to build a simple activity for messaging in android.




  • I have a RecyclerView that list the messages and I set a ScrollListener on it.

  • When the firstVisibleItem is the third of the list (RecyclerView stack from end), I will make a call to load other elements.

  • I add this element to my array and I set a new adapter on my RecyclerView for the update.

  • When I set the new adapter, the list starts one more time from the last message.

  • So far I have tried to use scrollToPosition to go to the message where the user was before scrollListener was triggered, but still not work at all because the lastVisibleItem become 1 every time.



Is there a way to maintain the last firstVisible element and set this element as the top element after reset the Adapter?



This is the onCreateMethod.



@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);

lastOffset = 0;
requestSize = 20;

loadMessage()

mAdapter = new ChatAdapter(this,mess);
llm = new LinearLayoutManager(this);
llm.setStackFromEnd(true);
mex_list.setLayoutManager(llm);
mex_list.setAdapter(mAdapter);
mex_list.addOnScrollListener(new RecyclerView.OnScrollListener()
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
super.onScrolled(recyclerView, dx, dy);
int lastVisible = llm.findLastVisibleItemPosition();
int firstVisible = llm.findFirstVisibleItemPosition();
lastFirstVisibleItem = firstVisibleItem; //lastFirstVisibleItem is a global variable
if(firstVisible <= 3)
if(!loading)
loading = true;
loadMessage();


Log.d("Test Scroll", "LAST: "+ lastVisible+" FIRST: "+firstVisible);

);


This is where the laodMessage() result was managed.



 public void manageResult(Object pr, int caller) 
if(caller == MESSAGES_REQ)
if(mess == null)
mess = new ArrayList<>();
ArrayList<Message> tail = (ArrayList<Message>) pr;

if(tail != null && tail.size() > 0)
lastOffset += tail.size();
mess.addAll(tail);
mAdapter = new ChatAdapter(ctx, mess);
mex_list.setAdapter(mAdapter);


llm.scrollToPosition(lastFirstVisibleItem);//lastFirstVisibleItem became always 1
spinner.setVisibility(View.GONE);
printEmpMex(View.GONE);
mex_list.setVisibility(View.VISIBLE);
loading = false;




This is the ChatAdapter.



public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ViewHolder> 

private ArrayList<Message> listOfMessages;
private static Context ctx;

private static final int SENT = 100;
private static final int RECIVED = 200;

public static class ViewHolder extends RecyclerView.ViewHolder
public TextView text;
public TextView hour;


public ViewHolder(View v)
super(v);
text = (TextView) v.findViewById(R.id.text_body);
hour = (TextView) v.findViewById(R.id.time);


void bind(Message m)
text.setText(m.getBody());
hour.setText(formatDateAndHour(m.getDate()));



public ChatAdapter(Context ctx, ArrayList<Message> m)
listOfMessages = m;
this.ctx = ctx;


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType)

View view;
if (viewType == SENT)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_sent, parent, false);
return new ViewHolder(view);


else if (viewType == RECIVED)

view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.single_mex_recived, parent, false);
return new ViewHolder(view);


return null;


@Override
public void onBindViewHolder(ViewHolder holder, int position)
Message mex = listOfMessages.get(position);
holder.bind(mex);


@Override
public int getItemCount()
return listOfMessages.size();


@Override
public int getItemViewType(int position)
Message m = listOfMessages.get(position);
if(m.getSender().getIdUser().equals(loggedUser.getIdUser()))
return SENT;
else
return RECIVED;



I really don't know how to make it work.
Every approach is welcome.



Thanks in advance.







android android-recyclerview infinite-scroll






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 16:16







Ferdinando D'avino

















asked Nov 12 '18 at 12:55









Ferdinando D'avinoFerdinando D'avino

6910




6910












  • Do you control ChatAdapter? Could you post its source code?

    – Ben P.
    Nov 12 '18 at 15:56











  • I have posted the code

    – Ferdinando D'avino
    Nov 12 '18 at 16:17












  • this link may help you stackoverflow.com/questions/31000964/…

    – Zahoor Saleem
    Nov 12 '18 at 16:31

















  • Do you control ChatAdapter? Could you post its source code?

    – Ben P.
    Nov 12 '18 at 15:56











  • I have posted the code

    – Ferdinando D'avino
    Nov 12 '18 at 16:17












  • this link may help you stackoverflow.com/questions/31000964/…

    – Zahoor Saleem
    Nov 12 '18 at 16:31
















Do you control ChatAdapter? Could you post its source code?

– Ben P.
Nov 12 '18 at 15:56





Do you control ChatAdapter? Could you post its source code?

– Ben P.
Nov 12 '18 at 15:56













I have posted the code

– Ferdinando D'avino
Nov 12 '18 at 16:17






I have posted the code

– Ferdinando D'avino
Nov 12 '18 at 16:17














this link may help you stackoverflow.com/questions/31000964/…

– Zahoor Saleem
Nov 12 '18 at 16:31





this link may help you stackoverflow.com/questions/31000964/…

– Zahoor Saleem
Nov 12 '18 at 16:31












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262638%2fscrolltoposition-for-lazy-loading-recyclerview%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53262638%2fscrolltoposition-for-lazy-loading-recyclerview%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Syphilis

Darth Vader #20