ScrollToPosition для отложенной загрузки RecyclerView - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь создать простое действие для обмена сообщениями в Android.

  • У меня есть RecyclerView, в котором перечислены сообщения, и я установил ScrollListener.
  • Когда firstVisibleItem является третьим в списке (RecyclerView stack from end), я позвоню, чтобы загрузить другие элементы.
  • Я добавляю этот элемент в свой массив и устанавливаю новый адаптер на RecyclerView для обновления.
  • Когда я устанавливаю новый адаптер, список начинается еще раз с последнего сообщения.
  • До сих пор я пытался использовать scrollToPosition, чтобы перейти к сообщению, в котором пользователь находился до запуска scrollListener, но все еще не работал вообще, потому что lastVisibleItem становится равным 1 каждый раз.

Есть ли способ сохранить последний элемент firstVisible и установить этот элемент в качестве верхнего элемента после сброса адаптера?

Это 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);
        }
    });}

Здесь был обработан результат laodMessage().

 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;
    }
}

Это 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;
}}

Я действительно не знаю, как заставить это работать. Любой подход приветствуется.

Заранее спасибо.

...