我已经导入了适当的库:“ 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/