Я пытаюсь создать простое действие для обмена сообщениями в 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;
}}
Я действительно не знаю, как заставить это работать.
Любой подход приветствуется.
Заранее спасибо.