我已经导入了适当的库:“ androidx.recyclerview.widget.RecyclerView”不知道问题是什么。请让我知道我是否应该使用此类提供xml布局代码。我正在尝试从Firebase获取聊天内容(文本),并在用户聊天窗口中查看它。

'''

公共类AdapterChat扩展了RecyclerView.Adapter {

private static final int MSG_TYPE_LEFT=0;
private static final int MSG_TYPE_RIGHT=1;
Context context;
List<ModelChat> chatList;
String imageUrl;

FirebaseUser fUser;

public AdapterChat(Context context, List<ModelChat> chatList, String imageUrl) {
    this.context = context;
    this.chatList = chatList;
    this.imageUrl = imageUrl;
}

@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    //inflate layouts: row_chat_left.xml for receiver ,row_chat_right for sender.
    if(viewType==MSG_TYPE_RIGHT){
        View view = LayoutInflater.from(context).inflate(R.layout.row_chat_right, parent, false);
        return new MyHolder(view);
    }

    else{
        View view = LayoutInflater.from(context).inflate(R.layout.row_chat_left, parent, false);
        return new MyHolder(view);
    }
}

@Override
public void onBindViewHolder(@NonNull MyHolder holder, int position) {
    //get data
    String message=chatList.get(position).getMessage();
    String timeStamp=chatList.get(position).getTimestamp();
    //convert timestamp to dd/mm/yyyy hh:mm am/pm format;

    Calendar cal=Calendar.getInstance(Locale.ENGLISH);
    cal.setTimeInMillis(Long.parseLong(timeStamp));
    String dateTime= DateFormat.format("dd/mm/yyyy hh:mm aa",cal).toString();

    //set Data
    holder.messageTv.setText(message);
    holder.timeTv.setText(dateTime);
    try{
        Picasso.get().load(imageUrl).into(holder.profileIv);

    }catch (Exception e){


    }

    //set seen /delivered status of message.
    if(position==chatList.size()-1){
        if(chatList.get(position).isSeen()) {
            holder.isSeenTv.setText("seen");
        }
        else {
            holder.isSeenTv.setText("delivered");
        }
    }
    else{
        holder.isSeenTv.setVisibility(View.GONE);

    }

}

@Override
public int getItemCount() {
    return chatList.size();
}
@Override
public int getItemViewType(int position) {
    //get currently signed in user.
    fUser= FirebaseAuth.getInstance().getCurrentUser();
    if(chatList.get(position).getSender().equals(fUser.getUid())){
        return  MSG_TYPE_RIGHT;

    }
    else {
        return MSG_TYPE_LEFT;
    }
    //return super.getItemViewType(position);
}


class MyHolder extends RecyclerView.ViewHolder{

    //views
    ImageView profileIv;
    TextView messageTv, timeTv,isSeenTv;


    public MyHolder(@NonNull View itemView) {
        super(itemView);

        //Init views
        profileIv =itemView.findViewById(R.id.profileIv);
        messageTv= itemView.findViewById(R.id.messageTv);
        timeTv= itemView.findViewById(R.id.timeTv);
        isSeenTv= itemView.findViewById(R.id.isSeenTv);
    }
}


}



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <com.mikhaellopez.circularimageview.CircularImageView
            android:visibility="gone"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:id="@+id/profileIv"
            app:civ_border_color="@null"
            android:src="@drawable/ic_default_img"/>
        <TextView
            android:id="@+id/timeTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="02/03/2020 05:59PM"
            android:textColor="@color/colorPrimaryDark"
            android:textSize="12sp">
        </TextView>
        <TextView
            android:id="@+id/messageTv"
            android:layout_weight="1"
            android:textSize="16sp"
            android:textColor="@color/colorPrimaryDark"
            android:background="@drawable/bg_sender"
            android:padding="15dp"
            android:text="His Message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/isSeenTv"
        android:layout_gravity="end"
        android:textAlignment="textEnd"
        android:text="delivered" />
</LinearLayout>





'''

聊天活动代码:

'''

公共类ChatActivity扩展了AppCompatActivity {

Toolbar toolbar;
RecyclerView recyclerView;
ImageView profileIv;
TextView nameTv, userStatusTv;
EditText messageEt;
ImageButton sendBtn;



FirebaseAuth firebaseAuth;
FirebaseDatabase firebaseDatabase;
DatabaseReference usersDbRef;


ValueEventListener seenListener;
DatabaseReference userRefForSeen;


List<ModelChat> chatList;
AdapterChat adapterChat;


String hisUid;
String myUid;
String hisImage;



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

    //init views

    Toolbar toolbar= findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    toolbar.setTitle("");
    recyclerView=findViewById(R.id.chat_recyclerView);
    profileIv=findViewById(R.id.profileIv);
    nameTv=findViewById(R.id.nameTv);
    userStatusTv=findViewById(R.id.userStatusTv);
    messageEt=findViewById(R.id.messageEt);
    sendBtn=findViewById(R.id.sendBtn);

    //Linear layout for recycler view
    LinearLayoutManager linearLayoutManager =new LinearLayoutManager(this);
    linearLayoutManager.setStackFromEnd(true);
    // recycler view properties:
    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(linearLayoutManager);



    Intent intent=getIntent();
    hisUid=intent.getStringExtra("hisUid");

    //Firebase auth instance.
    firebaseAuth= FirebaseAuth.getInstance();
    firebaseDatabase= FirebaseDatabase.getInstance();
    usersDbRef=firebaseDatabase.getReference("Users");
    //search user  to get that user's info
    Query userQuery= usersDbRef.orderByChild("uid").equalTo(hisUid);
    //get user Picture and name
    userQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            //check until required info is received
            for (   DataSnapshot ds:dataSnapshot.getChildren()){
                //get data
                String name =""+ds.child("setup_username").getValue();
                hisImage     =""+ds.child("image").getValue(); // might have to change it to the varibale name "username" used in firebase db.
                //set data
                nameTv.setText(name);
                try{
                    //image received set it ot imageview in toolbar.
                    Picasso.get().load(hisImage).placeholder(R.drawable.ic_default_img_white).into(profileIv);

                }
                catch (Exception e){
                    //if there is exception getting image ,set default pic;
                    Picasso.get().load(R.drawable.ic_default_img_white).into(profileIv);

                }
            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

    sendBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //get text from edit text
            String message=messageEt.getText().toString().trim();
            //check if text is empty or not
            if (TextUtils.isEmpty( message)){
                //Text is empty
                Toast.makeText(ChatActivity.this, "Can not send empty Message", Toast.LENGTH_SHORT).show();

            }
            else{
                ////Text is not empty
                sendMessage(message);

            }

        }
    });
    readMessages();
    seenMessage();

}

private void seenMessage() {
    userRefForSeen=FirebaseDatabase.getInstance().getReference("Chats");
    seenListener=userRefForSeen.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for(DataSnapshot ds:dataSnapshot.getChildren())
            {
                ModelChat chat=ds.getValue(ModelChat.class);
                if(chat.getReceiver().equals(myUid)&&chat.getSender().equals(hisUid))
                {
                    HashMap<String,Object>hasSeenHashmap=new HashMap<>();
                    hasSeenHashmap.put("isSeen",true);
                    ds.getRef().updateChildren(hasSeenHashmap);
                }

            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

private void readMessages() {
    chatList=new ArrayList<>();
    DatabaseReference dbRef= FirebaseDatabase.getInstance().getReference("Chats");
    dbRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            chatList.clear();
            for( DataSnapshot ds: dataSnapshot.getChildren()){
                ModelChat chat =ds.getValue(ModelChat.class);
                if(chat.getReceiver().equals(myUid)&&chat.getSender().equals(hisUid)|| chat.getReceiver().equals(hisUid)&&chat.getSender().equals(myUid))
                {
                    chatList.add(chat);
                }
                //adapter
                adapterChat=new AdapterChat(ChatActivity.this,chatList,hisImage );
                adapterChat.notifyDataSetChanged();
                //set Adapter to recycler view;
                recyclerView.setAdapter(adapterChat);

            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

}

private void sendMessage(String message) {


    DatabaseReference databaseReference= FirebaseDatabase.getInstance().getReference();
    String timestamp = String.valueOf(System.currentTimeMillis());
    HashMap<String, Object> hashMap=new HashMap<>();
    hashMap.put("sender",myUid);
    hashMap.put("receiver",hisUid);
    hashMap.put("message",message);
    hashMap.put("timestamp",timestamp);
    hashMap.put("isSeen",false);
    databaseReference.child("Chats").push().setValue(hashMap);
    //reset edit text after sending message:
    messageEt.setText("Type Message");// should be messageEt.setText("");

}


private void  checkUserStatus(){
    //get curr user
    FirebaseUser user=firebaseAuth.getCurrentUser();
    if (user!=null){
        //user is signed in stay here
        //set email of logged in user here
        //mProfileTv.setText(user.getEmail());
        myUid=user.getUid();//currently signd in user's uid
    }
    else{
        //user not signed in :redirect to main activity
        startActivity(new Intent(this,MainActivity.class));
        finish();
    }
}

@Override
protected void onStart() {
    checkUserStatus();
    super.onStart();
}

@Override
protected void onPause() {
    super.onPause();
    userRefForSeen.removeEventListener(seenListener);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main,menu);
    //hide searchview as we do not need it here.
    menu.findItem(R.id.action_search).setVisible(false);

    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    int id= item.getItemId();
    if(id==R.id.action_logout){
        firebaseAuth.signOut();
        checkUserStatus();
    }
    return super.onOptionsItemSelected(item);
}


}
'''

最佳答案

尝试在readMessages方法之外初始化适配器,这也说明了为什么适配器的构造函数中具有imageUrl参数,但是应该在ModelChat中,以获取回收器视图项的每一行不同的图像

private AdapterChat adapterChat;

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

    ...

    adapterChat = AdapterChat(this, chatList);
    recyclerView.setAdapter(adapterChat);

}


在适配器中,添加一个新功能(如setData),以从Firebase获取数据后进行设置,例如

void setData(ArrayList<ChatList> list) {
     this.chatList.clear()
     this.chatList.addAll(list);
     notifyDataSetChanged();
}


在readMessages方法变成这样

private void readMessages() {
    chatList=new ArrayList<>();
    DatabaseReference dbRef= FirebaseDatabase.getInstance().getReference("Chats");
    dbRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            chatList.clear();
            for( DataSnapshot ds: dataSnapshot.getChildren()){
                ModelChat chat =ds.getValue(ModelChat.class);
                if(chat.getReceiver().equals(myUid)&&chat.getSender().equals(hisUid)|| chat.getReceiver().equals(hisUid)&&chat.getSender().equals(myUid))
                {
                    chatList.add(chat);
                }
                //adapter set data
                adapterChat.setData(chatList);

            }

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

}

关于javascript - 我有错误:E/RecyclerView:未连接适配器;跳过布局,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60763996/

10-14 21:00