Java 为什么recyclerview ScrollToBottom不能有效工作?
我彻底搜索并尝试实现不同的东西,但似乎不可能 要求: 在我的聊天应用程序中,当我打开特定的用户聊天屏幕时Java 为什么recyclerview ScrollToBottom不能有效工作?,java,android,android-recyclerview,Java,Android,Android Recyclerview,我彻底搜索并尝试实现不同的东西,但似乎不可能 要求: 在我的聊天应用程序中,当我打开特定的用户聊天屏幕时 它应该滚动到底部,以便用户可以看到最后的消息/对话 当任何新的消息/新的项目将添加在那个时候,它应该滚动到底部 请注意,如果我使用以下方法,则我的第一个要求无效 private void loadMessages() { try { DatabaseReference messageReference = rootReference.child(MES
private void loadMessages() {
try {
DatabaseReference messageReference = rootReference.child(MESSAGES).child(currentUId).child(chatUser);
Query query = messageReference.orderByChild(TIME);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
messagesList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
try {
Messages messages = ds.getValue(Messages.class);
messagesList.add(messages);
setAdapter();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
databaseError.getMessage();
}
};
query.addValueEventListener(valueEventListener);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setAdapter() {
try {
if (mAdapter != null) {
mLayoutManager.smoothScrollToPosition(binding.recyclerViewLayout.recyclerView, null, messagesList.size());
mAdapter.notifyDataSetChanged();
} else {
mAdapter = new MessageAdapter(this, messagesList);
mLayoutManager.setStackFromEnd(false);
mLayoutManager.setSmoothScrollbarEnabled(true);
binding.recyclerViewLayout.recyclerView.setLayoutManager(mLayoutManager);
binding.recyclerViewLayout.recyclerView.setAdapter(mAdapter);
binding.recyclerViewLayout.recyclerView.setVisibility(View.VISIBLE);
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
如果我使用下面的方法,那么我的第二个要求不起作用强>
private void loadMessages() {
try {
DatabaseReference messageReference = rootReference.child(MESSAGES).child(currentUId).child(chatUser);
Query query = messageReference.orderByChild(TIME);
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
messagesList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
try {
Messages messages = ds.getValue(Messages.class);
messagesList.add(messages);
Comparator<Messages> compare = Collections.reverseOrder();
Collections.sort(messagesList, compare);
setAdapter();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
databaseError.getMessage();
}
};
query.addValueEventListener(valueEventListener);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setAdapter() {
try {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
} else {
mAdapter = new MessageAdapter(this, messagesList);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
mLayoutManager.setSmoothScrollbarEnabled(true);
binding.recyclerViewLayout.recyclerView.setLayoutManager(mLayoutManager);
binding.recyclerViewLayout.recyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
binding.recyclerViewLayout.recyclerView.setAdapter(mAdapter);
binding.recyclerViewLayout.recyclerView.setVisibility(View.VISIBLE);
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
private void loadMessages(){
试一试{
DatabaseReference messageReference=rootReference.child(MESSAGES).child(currentUId).child(chatUser);
Query Query=messageReference.orderByChild(时间);
ValueEventListener ValueEventListener=新的ValueEventListener(){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
messagesList.clear();
对于(DataSnapshot ds:DataSnapshot.getChildren()){
试一试{
Messages=ds.getValue(Messages.class);
messagesList.add(消息);
Comparator compare=Collections.reverseOrder();
Collections.sort(messagesList,compare);
setAdapter();
}捕获(例外e){
e、 printStackTrace();
}
}
}
@凌驾
已取消的公共void(DatabaseError DatabaseError){
databaseError.getMessage();
}
};
addValueEventListener(valueEventListener);
}捕获(例外e){
e、 printStackTrace();
}
}
私有void setAdapter(){
试一试{
如果(mAdapter!=null){
mAdapter.notifyDataSetChanged();
}否则{
mAdapter=newmessageadapter(这个,messagesList);
LinearLayoutManager mLayoutManager=新的LinearLayoutManager(此);
mLayoutManager.setReverseLayout(true);
mLayoutManager.setStackFromEnd(true);
mLayoutManager.setSmoothScrollbarEnabled(true);
binding.recyclerViewLayout.recyclerView.setLayoutManager(mlLayoutManager);
binding.recyclerViewLayout.recyclerView.scrollToPosition(mAdapter.getItemCount()-1);
binding.recyclerViewLayout.recyclerView.setAdapter(mAdapter);
binding.recyclerViewLayout.recyclerView.setVisibility(View.VISIBLE);
}
}捕获(异常扩展){
exp.printStackTrace();
}
}
请注意setAdapter()
,因为它在为每个循环调用时,第一次创建适配器,然后在循环的下一个增量立即调用notifydatasetchanged
编辑:
完整代码:编辑4:
addItem()
,notifyItemInserted(messagesList.size());addItem()
函数中添加一个函数
列表之后添加了recyclerView.scrollToPosition(mAdapter.getItemCount()-1);
sendbutonClickEvent()
添加recyclerView.scrollToPosition(mAdapter.getItemCount()-1);
注意:完整的代码在下面给出的链接中
main活动
package studio.devcode.recyclerviewdemo;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import studio.devcode.recyclerviewdemo.MessageAdapter;
import studio.devcode.recyclerviewdemo.Messages;
import studio.devcode.recyclerviewdemo.R;
public class MainActivity extends AppCompatActivity {
private ImageView imageViewSend;
private EditText editTextMessage;
private List<Messages> messagesList;
private MessageAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLayoutManager = new LinearLayoutManager(this);
recyclerView = findViewById(R.id.recycler_view_layout);
messagesList = new ArrayList<>();
imageViewSend = findViewById(R.id.send);
editTextMessage = findViewById(R.id.type_message);
setData("12345", "abc");
setData("12345", "hello");
setData("123145", "you");
setData("12345", "there");
setData("121345", "aqqqbc");
setData("123145", "abqqc");
setData("123145", "aqqbc");
setData("12345", "awwbc");
setData("123145", "eeabc");
setData("12345", "abeeec");
setData("112345", "addbc");
setData("12345", "abdcc");
setData("112345", "abccc");
setData("121345", "abccc");
setData("12345", "abccc");
setAdapter();
recyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
onSendButtonClick();
onSoftInputKeyboardOpen();
}
private void setData(String from, String message) {
messagesList.add(new Messages(message, "text", from));
}
private void onSendButtonClick(){
imageViewSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(!editTextMessage.getText().toString().isEmpty() || !editTextMessage.getText().toString().equals(" ")){
mAdapter.addItem(new Messages(editTextMessage.getText().toString().toUpperCase(), "text", "Ali"));
editTextMessage.setText("");
recyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
}
}
});
}
private void setAdapter() {
try {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
recyclerView.scrollToPosition(mAdapter.getItemCount());
} else {
mAdapter = new MessageAdapter(this, messagesList, "12345");
mLayoutManager.setSmoothScrollbarEnabled(true);
mLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setAdapter(mAdapter);
recyclerView.setVisibility(View.VISIBLE);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void onSoftInputKeyboardOpen(){
recyclerView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v,
int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom < oldBottom) {
recyclerView.postDelayed(new Runnable() {
@Override
public void run() {
recyclerView.smoothScrollToPosition(
recyclerView.getAdapter().getItemCount() - 1);
}
}, 100);
}
}
});
}
}
消息适配器
package studio.devcode.recyclerviewdemo;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MyViewHolder> {
private Context context;
private List<Messages> messagesList;
private String currentUid;
public MessageAdapter(Context context, List<Messages> messagesList, String currentUid) {
try {
this.currentUid = currentUid;
this.messagesList = messagesList;
this.context = context;
} catch (Exception e) {
e.printStackTrace();
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = null;
MyViewHolder myViewHolder;
try {
view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.message_single_layout, parent, false);
} catch (Exception e) {
e.printStackTrace();
}
myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
protected void showLog(String msg) {
Log.d(this.getClass().getSimpleName(), msg);
}
protected boolean checkNull(String data) {
return data != null && (!data.isEmpty());
}
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
try {
Messages messages = messagesList.get(position);
if (messages != null) {
String messageType = messages.getType();
if (checkNull(messages.getFrom()) && messages.getFrom().equals(currentUid)) {
if (checkNull(messageType) && messageType.equals("text")) {
holder.chatText_1.setText(messages.getMessage());
holder.messageSingleLayout.setVisibility(View.GONE);
holder.messageSingleLayout_1.setVisibility(View.VISIBLE);
}
} else {
if (checkNull(messageType) && messageType.equals("text")) {
holder.chatText.setText(messages.getMessage());
holder.messageSingleLayout.setVisibility(View.VISIBLE);
holder.messageSingleLayout_1.setVisibility(View.GONE);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int getItemCount() {
return messagesList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView chatText, chatText_1, chatTime, chatTime_1;
public LinearLayout messageSingleLayout, messageSingleLayout_1;
private final ImageView fileDownload;
private final ImageView fileDownload_1;
public MyViewHolder(View itemView) {
super(itemView);
chatText = itemView.findViewById(R.id.chatText);
chatText_1 = itemView.findViewById(R.id.chatText_1);
chatTime = itemView.findViewById(R.id.chatTime);
chatTime_1 = itemView.findViewById(R.id.chatTime_1);
messageSingleLayout = itemView.findViewById(R.id.messageSingleLayout);
messageSingleLayout_1 = itemView.findViewById(R.id.messageSingleLayout_1);
fileDownload = itemView.findViewById(R.id.fileDownload);
fileDownload_1 = itemView.findViewById(R.id.fileDownload_1);
}
}
public void addItem(Messages message) {
messagesList.add(message);
notifyItemInserted(messagesList.size());
}
}
package studio.devcode.recycleServiceWdemo;
导入android.content.Context;
导入android.os.Build;
导入android.util.Log;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.ImageView;
导入android.widget.LinearLayout;
导入android.widget.TextView;
导入androidx.annotation.NonNull;
导入androidx.recyclerview.widget.recyclerview;
导入java.util.List;
公共类MessageAdapter扩展了RecyclerView.Adapter{
私人语境;
私有列表消息列表;
私有字符串currentUid;
公共消息适配器(上下文上下文、列表消息列表、字符串currentUid){
试一试{
this.currentUid=currentUid;
this.messagesList=messagesList;
this.context=上下文;
}捕获(例外e){
e、 printStackTrace();
}
}
@非空
@凌驾
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup父级,int-viewType){
视图=空;
MyViewHolder MyViewHolder;
试一试{
view=LayoutInflater.from(parent.getContext()).flate(
R.layout.message_single_layout,parent,false);
}捕获(例外e){
e、 printStackTrace();
}
myViewHolder=新的myViewHolder(视图);
返回myViewHolder;
}
受保护的void showLog(字符串msg){
Log.d(this.getClass().getSimpleName(),msg);
}
受保护的布尔校验空(字符串数据){
返回数据!=null&(!data.isEmpty());
}
@凌驾
public void onBindViewHolder(@NonNull final MyViewHolder,int位置){
试一试{
Messages=messagesList.get(位置);
如果(消息!=null){
字符串messageType=messages.getType();
if(checkNull(messages.getFrom())&&messages.getFrom().equals(currentUid)){
如果(检查)
package studio.devcode.recyclerviewdemo;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MyViewHolder> {
private Context context;
private List<Messages> messagesList;
private String currentUid;
public MessageAdapter(Context context, List<Messages> messagesList, String currentUid) {
try {
this.currentUid = currentUid;
this.messagesList = messagesList;
this.context = context;
} catch (Exception e) {
e.printStackTrace();
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = null;
MyViewHolder myViewHolder;
try {
view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.message_single_layout, parent, false);
} catch (Exception e) {
e.printStackTrace();
}
myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
protected void showLog(String msg) {
Log.d(this.getClass().getSimpleName(), msg);
}
protected boolean checkNull(String data) {
return data != null && (!data.isEmpty());
}
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
try {
Messages messages = messagesList.get(position);
if (messages != null) {
String messageType = messages.getType();
if (checkNull(messages.getFrom()) && messages.getFrom().equals(currentUid)) {
if (checkNull(messageType) && messageType.equals("text")) {
holder.chatText_1.setText(messages.getMessage());
holder.messageSingleLayout.setVisibility(View.GONE);
holder.messageSingleLayout_1.setVisibility(View.VISIBLE);
}
} else {
if (checkNull(messageType) && messageType.equals("text")) {
holder.chatText.setText(messages.getMessage());
holder.messageSingleLayout.setVisibility(View.VISIBLE);
holder.messageSingleLayout_1.setVisibility(View.GONE);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int getItemCount() {
return messagesList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView chatText, chatText_1, chatTime, chatTime_1;
public LinearLayout messageSingleLayout, messageSingleLayout_1;
private final ImageView fileDownload;
private final ImageView fileDownload_1;
public MyViewHolder(View itemView) {
super(itemView);
chatText = itemView.findViewById(R.id.chatText);
chatText_1 = itemView.findViewById(R.id.chatText_1);
chatTime = itemView.findViewById(R.id.chatTime);
chatTime_1 = itemView.findViewById(R.id.chatTime_1);
messageSingleLayout = itemView.findViewById(R.id.messageSingleLayout);
messageSingleLayout_1 = itemView.findViewById(R.id.messageSingleLayout_1);
fileDownload = itemView.findViewById(R.id.fileDownload);
fileDownload_1 = itemView.findViewById(R.id.fileDownload_1);
}
}
public void addItem(Messages message) {
messagesList.add(message);
notifyItemInserted(messagesList.size());
}
}