回收者视图会多次加载视图项和不必要的空格

时间:2018-07-03 19:59:12

标签: android android-studio android-recyclerview

数据库中的消息树看起来如屏幕快照中所示。 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();
}


}

1 个答案:

答案 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