数据库中的消息树看起来如屏幕快照中所示。 Here is the database message tree。我正在尝试使用Firebase创建聊天应用程序。有时我发送的文本中出现不必要的空格。另外,某些文本会重复多次,并改变其位置。我需要帮助来解决此问题。空格的图像屏幕快照的链接位于:https://drive.google.com/file/d/16J4XXC2b1ZEWRAXe30G15sSLK6qB0V7A/view?usp=drivesdk
邮件位置更改消息的屏幕快照或回收站视图更改位置的项目视图的屏幕快照的链接位于:https://drive.google.com/file/d/1S81D_D-EELAMT03LSQEbr-D80FUQ-RCl/view?usp=drivesdk
主要聊天页面的我的activity_chat.xml如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".ChatActivity">
<include layout="@layout/app_bar_layout"
android:id="@+id/chat_bar_layout"></include>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/message_list_recycler_view"
android:layout_below="@+id/chat_bar_layout"
android:background="@drawable/chat"
android:layout_above="@+id/chat_message_linear_layout">
</android.support.v7.widget.RecyclerView>
<LinearLayout
android:id="@+id/chat_message_linear_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:background="@color/white">
<ImageButton
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginEnd="1dp"
android:layout_marginRight="1dp"
android:src="@drawable/ic_add_black_24dp"
android:id="@+id/chat_message_add_btn"
android:background="@color/white"
android:contentDescription="add"
/>
<EditText
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="8"
android:id="@+id/chat_message_edit_text"
android:paddingLeft="20dp"
android:background="@color/white"
android:hint="Enter message here"/>
<ImageButton
android:background="@color/white"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="1dp"
android:layout_marginStart="1dp"
android:id="@+id/chat_message_send_btn"
android:src="@drawable/ic_send_black_24dp"
android:contentDescription="send"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>
我对recyler视图项的单个消息布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_width="56dp"
android:layout_height="56dp"
android:src="@drawable/default_avatar"
android:id="@+id/message_single_profile_image"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:padding="10dp"
android:id="@+id/message_layout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"
android:id="@+id/chat_userName_single_text_view"
android:layout_marginLeft="20dp"
android:text="@string/user_name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/_00_00"
android:textSize="10sp"
android:layout_marginLeft="10dp"
android:id="@+id/time_single_text_view"
android:layout_toRightOf="@+id/chat_userName_single_text_view"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:textSize="14sp"
android:id="@+id/message_single_text_view"
android:textAlignment="viewStart"
android:layout_below="@+id/chat_userName_single_text_view" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/message_image"
android:layout_below="@+id/message_single_text_view"
android:layout_marginLeft="20dp" />
</RelativeLayout>
</LinearLayout>
我的ChatActivity.java文件在这里:
public class ChatActivity extends AppCompatActivity {
private String chat_user_id,chat_user_name,current_user_id;
private Toolbar mChatToolbar;
private FirebaseAuth mAuth;
private DatabaseReference mUsersRef,mRootRef;
private TextView chatUserName,chatUserLastSeen;
private CircleImageView chatUserImage;
private EditText chatMessageEditText;
private ImageButton chatMessageAddBtn,chatMessageSendBtn;
private RecyclerView mMessageList;
private final List<Messages> messagesList = new ArrayList<>();
private LinearLayoutManager mLinearLayout;
private MessageAdapter mAdapter;
private boolean exist ;
private static final int TOTAL_ITEMS_TO_LOAD = 10;
private static final int GALLERY_PICK =1;
private StorageReference mImageStorage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
chat_user_id = getIntent().getStringExtra("user_id");
chat_user_name = getIntent().getStringExtra("chatUserName");
mChatToolbar = findViewById(R.id.chat_bar_layout);
mImageStorage = FirebaseStorage.getInstance().getReference();
setSupportActionBar(mChatToolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
mAuth = FirebaseAuth.getInstance();
if (mAuth!=null)
{
current_user_id = mAuth.getCurrentUser().getUid();
}
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View cutom_view = inflater.inflate(R.layout.chat_custom_bar,null);
actionBar.setCustomView(cutom_view);
chatUserName = findViewById(R.id.custom_bar_display_name);
chatUserLastSeen = findViewById(R.id.custom_bar_last_seen);
chatUserImage = findViewById(R.id.custom_bar_image);
chatUserName.setText(chat_user_name);
chatMessageEditText = findViewById(R.id.chat_message_edit_text);
chatMessageAddBtn = findViewById(R.id.chat_message_add_btn);
chatMessageSendBtn = findViewById(R.id.chat_message_send_btn);
mAdapter = new MessageAdapter(messagesList);
mMessageList = findViewById(R.id.message_list_recycler_view);
mLinearLayout = new LinearLayoutManager(this);
mMessageList.setHasFixedSize(true);
mMessageList.setLayoutManager(mLinearLayout);
mMessageList.setAdapter(mAdapter);
mRootRef = FirebaseDatabase.getInstance().getReference();
mUsersRef = FirebaseDatabase.getInstance().getReference().child("Users");
loadMessages();
Toast.makeText(this, "messages loading...", Toast.LENGTH_SHORT).show();
mUsersRef.child(chat_user_id).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String thumbImage = dataSnapshot.child("thumb_image").getValue().toString();
Picasso.with(ChatActivity.this).load(thumbImage).placeholder(R.drawable.default_avatar2).into(chatUserImage);
String online = dataSnapshot.child("online").getValue().toString();
if (online.equals("true"))
{
chatUserLastSeen.setText("Online");
}
else
{
GetTimeAgo getTimeAgo = new GetTimeAgo();
long last_seen = Long.parseLong(online);
String last_seen_time = getTimeAgo.getTimeAgo(last_seen,getApplicationContext());
chatUserLastSeen.setText(last_seen_time);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
chatMessageSendBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMessage();
}
});
chatMessageAddBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(galleryIntent,"Select Image"),GALLERY_PICK);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICK && resultCode == RESULT_OK) {
Uri imageUri = data.getData();
final String currentUserRef = "messages/" + current_user_id + "/" + chat_user_id;
final String chatUserRef = "messages/" + chat_user_id + "/" + current_user_id;
DatabaseReference messageUserRef = mRootRef.child("messages").child(current_user_id).child(chat_user_id).push();
final String pushId = messageUserRef.getKey();
StorageReference filePath = mImageStorage.child("message_images").child(pushId+".jpg");
filePath.putFile(imageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
@Override
public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
String downloadUrl = task.getResult().getDownloadUrl().toString();
Map messageMap = new HashMap();
messageMap.put("message", downloadUrl);
messageMap.put("seen", false);
messageMap.put("type", "image");
messageMap.put("time", ServerValue.TIMESTAMP);
messageMap.put("from", current_user_id);
Map messageUserMap = new HashMap();
messageUserMap.put(currentUserRef + "/" + pushId, messageMap);
messageUserMap.put(chatUserRef + "/" + pushId, messageMap);
chatMessageEditText.setText("");
mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null) {
Toast.makeText(ChatActivity.this, databaseError.getMessage().toString(), Toast.LENGTH_SHORT).show();
} else {
loadMessages();
}
}
});
}
}
});
}
}
private void loadMessages() {
//
DatabaseReference messagesRef = mRootRef.child("messages").child(current_user_id).child(chat_user_id);
messagesRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Messages messages = dataSnapshot.getValue(Messages.class);
messagesList.add(messages);
mAdapter.notifyDataSetChanged();
mMessageList.scrollToPosition(messagesList.size());
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
// }
}
private void sendMessage() {
String message = chatMessageEditText.getText().toString();
if (!TextUtils.isEmpty(message)) {
String currentUserRef = "messages/" + current_user_id + "/" + chat_user_id;
String chatUserRef = "messages/" + chat_user_id + "/" + current_user_id;
String currentUserMessageRef = "lastMessage/" + current_user_id + "/" + chat_user_id;
String chatUserMessageRef = "lastMessage/" + chat_user_id + "/" + current_user_id;
DatabaseReference messageUserRef = mRootRef.child("messages").child(current_user_id).child(chat_user_id).push();
String pushId = messageUserRef.getKey();
Map messageMap = new HashMap();
messageMap.put("message", message);
messageMap.put("seen", false);
messageMap.put("type", "text");
messageMap.put("time", ServerValue.TIMESTAMP);
messageMap.put("from",current_user_id);
Map messageUserMap = new HashMap();
messageUserMap.put(currentUserRef + "/" + pushId,messageMap);
messageUserMap.put(chatUserRef + "/" + pushId,messageMap);
Map lastMessageMap = new HashMap();
lastMessageMap.put("lastMessageKey",pushId);
Map lastMessageUserMap = new HashMap();
lastMessageUserMap.put(currentUserMessageRef ,lastMessageMap);
lastMessageUserMap.put(chatUserMessageRef ,lastMessageMap);
chatMessageEditText.setText("");
mRootRef.updateChildren(messageUserMap, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null)
{
Toast.makeText(ChatActivity.this, databaseError.getMessage().toString() , Toast.LENGTH_SHORT).show();
}
else {
loadMessages();
}
}
});
mRootRef.updateChildren(lastMessageUserMap, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null)
{
Toast.makeText(ChatActivity.this, databaseError.getMessage().toString(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
@Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser == null) {
sendToStart();
}
else {
mUsersRef.child(currentUser.getUid()).child("online").setValue("true");
}
}
@Override
protected void onStop() {
super.onStop();
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser != null) {
mUsersRef.child(currentUser.getUid()).child("online").setValue(ServerValue.TIMESTAMP);
}
}
private void sendToStart() {
Intent startIntent = new Intent(ChatActivity.this,StartActivity.class);
startActivity(startIntent);
finish();
}
}
答案 0 :(得分:0)
要固定邮件的高度,请在此处将accept()
更改为match_parent
:
wrap_content
要确定消息的顺序,请像这样将<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:textSize="14sp"
android:id="@+id/message_single_text_view"
添加到数据库引用中:
orderByChild