具有多个布局的 ListView - 如何在给定布局中保留每一行

如何解决具有多个布局的 ListView - 如何在给定布局中保留每一行

我有以下布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textGoesHere"
        android:drawableRight="@drawable/row_receive"
        android:text="hello alert" />

</RelativeLayout>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textGoesHere"
        android:drawableLeft="@drawable/row_send"
        android:text="hello alert" />

</LinearLayout>

我正在尝试创建一个显示这两种布局的 ListView。这是我的 java 代码,它具有主类、一个 Message 类,用于存储来自 EditText 的数据,用户填写并应该填充 ListView,最后是自定义 Adapter 类:

package com.example.androidlabs;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class ChatRoomActivity extends AppCompatActivity {

    List<String> listElements = new ArrayList<String>();
    ListView theListView;
    Button sendButton;
    Button receiveButton;
    EditText chatText;
    Adapter adapter;
    Message message = new Message();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat_room);

        theListView = (ListView) findViewById(R.id.theListView);
        sendButton = (Button) findViewById(R.id.sendButton);
        chatText = (EditText) findViewById(R.id.chatText);
        receiveButton = (Button) findViewById(R.id.receiveButton);

        theListView.setAdapter(adapter = new Adapter());

       // sendButton.setonClickListener(click -> listElements.add("new element"));
       sendButton.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)  {
                message.setMessage(chatText.getText().toString());
                message.setType(0);
                listElements.add(chatText.getText().toString());
                adapter.notifyDataSetChanged();
            }
        });

        receiveButton.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)  {
                message.setMessage(chatText.getText().toString());
                message.setType(1);
                listElements.add(chatText.getText().toString());
                adapter.notifyDataSetChanged();
            }
        });
    }

    public class Message {
        private String text;
        private int type;

        public void setMessage(String text) { this.text = text; }
        public String getMessage()  { return text; }

        public void setType(int type)  { this.type = type; }
        public int getType()  {return type; }
        }

    public class Adapter extends BaseAdapter {

        @Override
        public int getViewTypeCount()  {
            return 2;
        }

        @Override
        public int getItemViewType(int position)  {
            if (message.getType() == 0) { return 0; }
            else { return 1; }
        }
        @Override
        public int getCount() {
            return listElements.size();
        }

        @Override
        public Object getItem(int position) {
            return listElements.get(position);
        }

        @Override
        public long getItemId(int position) {
            return (long) position;
        }

        @Override
        public View getView(int position,View old,ViewGroup parent) {

            View newView = old;
            LayoutInflater inflater = getLayoutInflater();
            int listViewItemType = this.getItemViewType(position);

            //make a new row
            if (newView == null)  {

                if (listViewItemType == 0) {
                    newView = inflater.inflate(R.layout.row_send_layout,parent,false);
                }
                else  {
                    newView = inflater.inflate(R.layout.row_receive_layout,false);
                }

            }

            //set what the text should be for this row:
            TextView tView = newView.findViewById(R.id.textGoesHere);
            tView.setText( getItem(position).toString() );

            //return it to be put in the table
            return newView;
        }
    }
}

我希望列表视图如下所示:

The ListView I want

但最终发生的是它根据用户点击的按钮改变了 ListView 的所有布局:

The ListView I get if I click on "Send"

The ListView I get if I click on "Recieve"

我可以在我的代码中进行哪些调整以获得所需的结果?我假设它在我的 getView() 方法中,但我不知道那是什么。

解决方法

您经常使用对 Message 的相同引用:
Message message = new Message();

因此,当发送新消息时,它也会完全覆盖旧消息。您通过将文本存储在上面的 ArrayList 中来保存文本,因此当布局刷新时,它只是从那里加载文本,但消息类型会一遍又一遍地从单个消息中读取...>

要修复它,您还需要将 Message 放在 Array/ArrayList 中。这样做时,我还会删除 listElements-Arraylist,因为它只存储与消息本身存储的相同的消息......两次存储相同的数据是一种不好的做法,因为这可能会导致问题仅更改其中之一时。

因此,不要在您的 setMessage 中调用 setTypeonClickListener 方法,而是创建 Message 的新实例,用数据填充它并将其存储在 ArrayList 中{1}}。然后,在适配器的 getViewgetItemViewType 函数中,从传入的 position 参数中获取所需的消息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?