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.

0 Answers0