【发布时间】:2022-02-07 04:01:51
【问题描述】:
谁能帮帮我???
问题陈述:我正在制作一个在 ChatActivity 中几乎准备就绪的聊天应用程序。功能是用户可以一起发送图像和文本,但在发送文本时它很好。当我发送图像时,问题就开始了。发送后,当我向上滚动到我的所有文本开始变为最近发送的图像。
ChatActivity.xml -
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/bg_light"
tools:context=".ChatActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/backArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_back_arrow"
app:tint="@color/white" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/profile_image"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_marginStart="5dp"
android:padding="5dp"
android:src="@drawable/avatar"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/backArrow"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/userName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="3dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="13dp"
android:fontFamily="@font/roboto"
android:text=""
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageView7"
app:layout_constraintStart_toEndOf="@+id/profile_image"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/lastSeen"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="2dp"
android:fontFamily="@font/roboto_light"
android:text=""
android:textColor="@color/white"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageView7"
app:layout_constraintStart_toEndOf="@+id/profile_image"
app:layout_constraintTop_toBottomOf="@+id/userName" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="-22dp" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="left"
tools:layout_editor_absoluteX="395dp" />
<ImageView
android:id="@+id/imageView7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_more"
app:tint="@color/white" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chatRecyclerView"
android:layout_width="match_parent"
android:layout_height="611dp"
android:nestedScrollingEnabled="false">
</androidx.recyclerview.widget.RecyclerView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="4dp">
<View
android:id="@+id/view14"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/follow_active_btn"
app:layout_constraintBottom_toBottomOf="@+id/etMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/etMessage" />
<EditText
android:id="@+id/etMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="4dp"
android:background="@color/transparent"
android:ems="10"
android:hint="Message"
android:inputType="textMultiLine"
android:maxLines="4"
android:minHeight="48dp"
android:paddingStart="4dp"
android:paddingLeft="4dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/sendMessageImage"
app:layout_constraintStart_toStartOf="parent" />
<ImageView
android:id="@+id/sendMessage"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="8dp"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="@+id/etMessage"
app:layout_constraintEnd_toEndOf="@+id/view14"
app:layout_constraintTop_toTopOf="@+id/etMessage"
app:srcCompat="@drawable/comment"
app:tint="@color/purple_500" />
<ImageView
android:id="@+id/sendMessageImage"
android:layout_width="36dp"
android:layout_height="36dp"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="@+id/sendMessage"
app:layout_constraintEnd_toStartOf="@+id/sendMessage"
app:layout_constraintTop_toTopOf="@+id/sendMessage"
app:srcCompat="@drawable/clip"
app:tint="@color/black" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
ChatAdapter.java -
package com.codinggeekers.lmsbeta.Adapter;
import android.content.Context;
import android.media.Image;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.codinggeekers.lmsbeta.Models.MessageModel;
import com.codinggeekers.lmsbeta.R;
import com.google.firebase.auth.FirebaseAuth;
import com.squareup.picasso.Picasso;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
public class ChatAdapter extends RecyclerView.Adapter {
ArrayList<MessageModel> list;
Context context;
int SENDER_VIEW_TYPE = 1;
int RECEIVER_VIEW_TYPE = 2;
public ChatAdapter(ArrayList<MessageModel> list, Context context) {
this.list = list;
this.context = context;
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if(viewType == SENDER_VIEW_TYPE) {
View view = LayoutInflater.from(context).inflate(R.layout.sample_sender, parent, false);
return new SenderViewHolder(view);
}
else {
View view = LayoutInflater.from(context).inflate(R.layout.sample_receiver, parent, false);
return new ReceiverViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
MessageModel message = list.get(position);
Timestamp ts = new Timestamp(message.getTimestamp());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm a");
String time = simpleDateFormat.format(ts.getTime());
RequestOptions requestOptions = new RequestOptions();
requestOptions = requestOptions.transforms(new CenterCrop(), new RoundedCorners(10));
if(holder.getClass() == SenderViewHolder.class) {
if (message.getMsgImg()!=null) {
((SenderViewHolder)holder).senderImageLayout.setVisibility(View.VISIBLE);
((SenderViewHolder)holder).senderTextLayout.setVisibility(View.GONE);
// Picasso.get().load(message.getMsgImg()).placeholder(R.drawable.placeholder).into(((SenderViewHolder)holder).senderImage);
Glide.with(((SenderViewHolder)holder).itemView.getContext()).load(message.getMsgImg()).apply(requestOptions)
.placeholder(R.drawable.placeholder).into(((SenderViewHolder)holder).senderImage);
} else {
((SenderViewHolder)holder).senderMsg.setText(message.getMessage());
((SenderViewHolder)holder).senderTime.setText(time);
}
}
else {
if (message.getMsgImg()!=null) {
((ReceiverViewHolder)holder).receiverImageLayout.setVisibility(View.VISIBLE);
// Picasso.get().load(message.getMsgImg()).placeholder(R.drawable.placeholder).into(((ReceiverViewHolder)holder).receiverImage);
Glide.with(((ReceiverViewHolder)holder).itemView.getContext()).load(message.getMsgImg()).apply(requestOptions)
.placeholder(R.drawable.placeholder).into(((ReceiverViewHolder)holder).receiverImage);
} else {
((ReceiverViewHolder)holder).receiverMsg.setText(message.getMessage());
((ReceiverViewHolder)holder).receiverTime.setText(time);
}
}
}
@Override
public int getItemViewType(int position) {
if(list.get(position).getuId().equals(FirebaseAuth.getInstance().getUid())) {
return SENDER_VIEW_TYPE;
}
else {
return RECEIVER_VIEW_TYPE;
}
}
@Override
public int getItemCount() {
return list.size();
}
public class ReceiverViewHolder extends RecyclerView.ViewHolder {
TextView receiverMsg, receiverTime;
ImageView receiverImage;
ConstraintLayout receiverImageLayout;
public ReceiverViewHolder(@NonNull View itemView) {
super(itemView);
receiverMsg = itemView.findViewById(R.id.receiverText);
receiverTime = itemView.findViewById(R.id.receiverTime);
receiverImage = itemView.findViewById(R.id.receiverImage);
receiverImageLayout = itemView.findViewById(R.id.imageConstraintLayoutReceiver);
}
}
public class SenderViewHolder extends RecyclerView.ViewHolder {
TextView senderMsg, senderTime;
ImageView senderImage;
ConstraintLayout senderImageLayout;
ConstraintLayout senderTextLayout;
public SenderViewHolder(@NonNull View itemView) {
super(itemView);
senderMsg = itemView.findViewById(R.id.senderText);
senderTime = itemView.findViewById(R.id.senderTime);
senderImage = itemView.findViewById(R.id.senderImage);
senderImageLayout = itemView.findViewById(R.id.imageConstraintLayoutSender);
senderTextLayout = itemView.findViewById(R.id.textConstraintLayoutSender);
}
}
}
ChatActivity.java -
package com.codinggeekers.lmsbeta;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import com.codinggeekers.lmsbeta.Adapter.ChatAdapter;
import com.codinggeekers.lmsbeta.Models.MessageModel;
import com.codinggeekers.lmsbeta.databinding.ActivityChatBinding;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
import java.util.Date;
public class ChatActivity extends AppCompatActivity {
ActivityChatBinding binding;
ProgressDialog dialog;
FirebaseAuth auth;
FirebaseDatabase database;
FirebaseStorage storage;
ActivityResultLauncher<String> galleryLauncher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityChatBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
auth = FirebaseAuth.getInstance();
database = FirebaseDatabase.getInstance();
storage = FirebaseStorage.getInstance();
dialog = new ProgressDialog(this);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setTitle("Sending Image...");
dialog.setMessage("Please wait...");
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
// Sender and Receiver Ids
final String senderId = auth.getUid();
String receiveId = getIntent().getStringExtra("userId");
String userName = getIntent().getStringExtra("userName");
String profilePic = getIntent().getStringExtra("profilePic");
binding.userName.setText(userName);
Picasso.get().load(profilePic).placeholder(R.drawable.avatar).into(binding.profileImage);
binding.backArrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ChatActivity.this, UsersChatActivity.class);
startActivity(intent);
}
});
final ArrayList<MessageModel> messageModels = new ArrayList<MessageModel>();
final ChatAdapter chatAdapter = new ChatAdapter(messageModels, this);
binding.chatRecyclerView.setAdapter(chatAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
binding.chatRecyclerView.setHasFixedSize(true);
binding.chatRecyclerView.setLayoutManager(layoutManager);
final String senderRoom = senderId + receiveId;
final String receiverRoom = receiveId + senderId;
database.getReference().child("Chats")
.child(senderRoom)
.addValueEventListener(new ValueEventListener() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
messageModels.clear();
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
MessageModel model = snapshot1.getValue(MessageModel.class);
messageModels.add(model);
}
chatAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
binding.sendMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String message = binding.etMessage.getText().toString();
if (message.matches("")) {
} else {
final MessageModel model = new MessageModel(senderId, message, "text");
model.setTimestamp(new Date().getTime());
binding.etMessage.setText("");
database.getReference().child("Chats")
.child(senderRoom)
.push()
.setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(@NonNull Void unused) {
database.getReference().child("Chats").child(receiverRoom).push().setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(@NonNull Void unused) {
}
});
}
});
}
}
});
binding.sendMessageImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
galleryLauncher.launch("image/*");
}
});
galleryLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri result) {
dialog.show();
final StorageReference reference = storage.getReference().child("chats")
.child(senderRoom).child(new Date().getTime() + "");
reference.putFile(result).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
final MessageModel model = new MessageModel(senderId, new Date().getTime(), uri.toString(), "image");
database.getReference()
.child("Chats")
.child(senderRoom)
.push()
.setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void unused) {
database.getReference().child("Chats").child(receiverRoom).push().setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void unused) {
dialog.dismiss();
binding.sendMessageImage.setImageURI(Uri.EMPTY);
Intent intent = getIntent();
finish();
startActivity(intent);
}
});
}
});
}
});
}
});
}
});
binding.userName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(ChatActivity.this, FriendsProfileActivity.class);
intent.putExtra("userName", userName);
intent.putExtra("userId", receiveId);
intent.putExtra("profilePic", profilePic);
startActivity(intent);
}
});
}
}
【问题讨论】:
-
如果您遇到问题,最好在发布问题时创建MCVE。您为此问题发布了近 600(六百)行行代码。人们需要解析和尝试在线调试的内容很多。请编辑您的问题并隔离问题,这样可以增加获得帮助的机会。
-
好的,谢谢建议,我会的
标签: java android firebase firebase-realtime-database android-recyclerview