java - Android - FirebaseListAdapter 复制运行时布局更改

标签 java android firebase

我来这里是为了询问是否有人知道我无法解决的问题的解决方法。

基本上,我正在使用 Firebase 在 Android 中编写一个简单的聊天应用程序作为练习。我在主布局中使用 ListView ,并在每个“消息气泡”中使用一个简单的布局。问题来了:当我可视化从 Firebase 检索的消息时,我在运行时根据当前用户更改气泡的颜色,首次加载时每个气泡都有正确的颜色,但是通过上下滚动我的消息,越来越多的气泡呈现“ActiveUser”颜色,即使它们属于不同的用户,有什么想法吗?我将把我正在使用的代码留在下面

主布局ListView

 <ListView
    android:id="@+id/list_of_messages"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/inputArea"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:divider="@android:color/transparent"
    android:dividerHeight="16dp"
    android:paddingStart="15dp"
    android:paddingBottom="5dp"
    android:paddingEnd="15dp"
    android:paddingTop="10dp"/>

消息气泡布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="@+id/message_bubble"
android:background="@drawable/normal_message_background">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:id="@+id/message_user"
    android:textStyle="normal|bold" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toEndOf="@id/message_user"
    android:layout_marginStart="10dp"
    android:id="@+id/message_time" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/message_user"
    android:layout_alignParentStart="true"
    android:layout_marginTop="5dp"
    android:id="@+id/message_text"
    android:textAppearance="@style/TextAppearance.AppCompat.Body1"
    android:textSize="18sp" />

FirebaseListAdapter 和运行时样式更改代码块

private void displayChatMessages() {

    ListView listOfMessages = findViewById(R.id.list_of_messages);

   FirebaseListOptions<ChatMessage> options = new FirebaseListOptions.Builder<ChatMessage>().setLayout(R.layout.message)
            .setQuery(dbMessagesReference, ChatMessage.class).build();

    mAdapter = new FirebaseListAdapter<ChatMessage>(options) {
        @Override
        protected void populateView(View v, ChatMessage model, int position) {
            // Get references to the views of message.xml

            RelativeLayout messageBubble = v.findViewById(R.id.message_bubble);
            TextView messageText = v.findViewById(R.id.message_text);
            TextView messageUser = v.findViewById(R.id.message_user);
            TextView messageTime = v.findViewById(R.id.message_time);

            // Set their text
            messageText.setText(model.getMessageText());
            messageUser.setText(model.getMessageUser());
            messageTime.setText(model.getMessageTime());

            if (messageUser.getText().equals(FirebaseAuth.getInstance().getCurrentUser().getDisplayName()))
                messageBubble.setBackgroundResource(R.drawable.active_user_message_background);

        }
    };

    listOfMessages.setAdapter(mAdapter);

}

编辑: 我通过声明 else 语句来解决这个问题,如果用户名不匹配,则将正常的可绘制变体设置回来,但是一旦在运行时更改了背景资源,气泡看起来更小并且不会环绕所有文本,有谁知道其中的原因吗?

第二次编辑: 我在另一篇文章中找到了第二个问题的解决方案:Where'd padding go, when setting background Drawable?

显然该问题应该已在 API 19/21 中得到解决,但是如果您仍然遇到该问题,请应用上面链接的线程中解释的解决方法

最佳答案

ListView 将重用 View 来帮助提高性能。这意味着当我们滚动时,适配器只会将您的内容放置在原本要离开屏幕的 View 中,而不是展开新 View 。这会导致您设置当前用户背景的所有 View 始终保留该背景,因为如果 View 填充了非当前用户数据,则没有条件将其设置回来。

要解决此问题,请添加以下条件:

if (messageUser.getText().equals(FirebaseAuth.getInstance().getCurrentUser().getDisplayName())){                
 messageBubble.setBackgroundResource(R.drawable.active_user_message_background);
}
else{
    messageBubble.setBackgroundResource(R.drawable.normal_message_background);
}

关于java - Android - FirebaseListAdapter 复制运行时布局更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50930638/

相关文章:

android - 这些错误在我的 react-native 项目中的 React-Native 中意味着什么,我该如何修复它们?

node.js - TypeError : result[0]. 数据不是函数

ios - Firebase Offline,确定项目是否保存到服务器而不仅仅是本地缓存

java - Android 应用程序无法在设备上运行

java - 如何指示 Windows 报告我的 Java 应用程序的名称而不是 java.exe

java - 如何在添加新行后自动对 JTable 进行排序?

java - 如何使用 ListViews 创建选项卡式 Activity - Android

java - 查找 self 和运行时 jar

android - 添加到 FragmentContainerView 的 View 必须与 Fragment 关联

java - 如何作为方法的结果返回 DocumentSnapShot?