2943 字
15 分钟
Android学习笔记——ListView列表

界面搭建的三个必备属性#

id,width,height

<ListView
        android:id="@+id/lv_lv_lv"
        android:layout_width="match_parent"
        android:layout_height="300dp"

LIstView实现数据映射的三个要素:#

ListView列表视图ListView列表视图#

ListView 是一个容器控件,用于显示可滚动的列表。它可以在界面上垂直显示多个项目(如文本、图片、控件等),通常用于显示大量数据。

数据(文本、图片、控件)#

String abcd = "1234";
String[] str = {"1","2","3"};

适配器(Adapter)将数据映射到ListView列表视图的桥梁#

ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, data);

Map类#

Map类基本用法,如何实例化?#

Map类是Java中用于存储键值对的数据结构。基本的使用方法包括添加和获取键值对、判断是否包含某个键、获取键的集合、获取值的集合等。

使用HashMap类实例化Map对象 使用TreeMap类实例化Map对象 使用LinkedHash类实例化Map对象 HasMap是Map的子类 用来完成实例化操作

Map<String, Integer> map = new HashMap<>(); // 使用 HashMap 实例化 Map,其中键是字符串,值是整数

Map类型对象如何放入数据?#

实例化 Map 对象: 首先,你需要实例化一个 Map 对象,通常使用 HashMap 实现。可以使用泛型来指定键和值的类型。

Map<String, Integer> map = new HashMap<>();

放入数据: 使用 put 方法将键-值对放入 Map 对象。

map.put("apple", 5);     // 放入键 "apple" 和对应的值 5
map.put("banana", 3);    // 放入键 "banana" 和对应的值 3
map.put("cherry", 10);   // 放入键 "cherry" 和对应的值 10

遍历 Map: 你可以遍历 Map 的键-值对。

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    String key = entry.getKey();    // 获取键
    int value = entry.getValue();   // 获取值
    System.out.println("Key: " + key + ", Value: " + value);
}

ArrayList类#

实例化 ArrayList: 你可以使用 ArrayList 类实例化一个动态数组。

ArrayList<String> list = new ArrayList<>();

添加元素: 你可以使用 add 方法来添加元素到 ArrayList。

list.add("apple");      // 添加元素 "apple" 到 ArrayList
list.add("banana");     // 添加元素 "banana" 到 ArrayList
list.add("cherry");     // 添加元素 "cherry" 到 ArrayList

Arraylist类包包含的数据类型有哪些?

任何引用类型(Reference Types): 这包括类、接口、自定义数据类型等。你可以将任何引用类型的对象添加到 ArrayList 中。 基本数据类型的包装类(Wrapper Classes): 例如 Integer、Double、Boolean 等。这是因为 ArrayList 不能直接包含基本数据类型,但可以包含其对应的包装类对象。 字符串(String): 你可以将字符串对象添加到 ArrayList 中,使其成为字符串列表。 自定义类对象: 如果你创建了自定义类,可以将该类的对象添加到 ArrayList 中。 其他集合类型: 你可以将其他集合类型,如 ArrayList、LinkedList 等,作为元素添加到外部 ArrayList 中。

ListViewActivity类的搭建#

声明变量#

private ListView listView;

添加数据数组#

String[] contacts = {"联系人1","联系人2","联系人3","联系人4","联系人5","联系人6"};
String[] tels = {"手机号1","手机号2","手机号3","手机号4","手机号5","手机号6",};

初始化操作#

initView();

绑定控件#

listView = findViewById(R.id.lv_lv_lv);

创建适配器#

ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
                getApplicationContext(),
                android.R.layout.simple_list_item_1,
                contacts
        );

设置适配器#

mLv1.setAdapter(arrayAdapter);

实例化Map#

ArrayList<Map<String,Object>> mData =new ArrayList<>();

手机号 -tel归属地
手机号1 tels[0]归属地1 addrs[0]
手机号2 tels[1]归属地2 addrs[1]
手机号3 tels[2]归属地3 addrs[2]
手机号4 tels[3]归属地4 addrs[3]
手机号5 tels[4]归属地5 addrs[4]
手机号6 tels[5]归属地6 addrs[5]

一行对应一个Map,首先就声明Map类型的对象,并进行实例化操作

Map<String,Object> map = new HashMap<>();

Map基本结构 key-value 的形式key类型

将数据放在Arraylist里(看作是一个二维表)中去, 当需要加载多条相同结构的数据时必须要用到循环——for语句

for(int i=0;i<tels.length;i++){
            //首先就声明Map类型的对象,并进行实例化操作——对应一行的操作
            Map<String,Object> map = new HashMap<>();
            //将数据压入Map中
            map.put("tel",tels[i]);
            map.put("addr",addrs[i]);
            //将map中存放的一行的数据存入二维表格中去
            mData.add(map);
        }

创建适配器#

SimpleAdapter simpleAdapter = new SimpleAdapter(
                getApplicationContext(),
                mData,
                android.R.layout.simple_list_item_2,
                new String[]{"tel","addr"},
                new int[]{android.R.id.text1,android.R.id.text2}
        );

参数1:上下文关系——getApplicationContext() 参数2:数据——List<? extends Map<String,Object>> 参数3:布局——使用系统提供的固定的布局 参数4:数据从哪里来?——每一行数据存放过程中使用的key,构成了一个字符串数组,必须和存放数据的key完全一致 参数5:数据存到哪个控件上去?——固定布局中的2个TextView控件对应的id,构成了一个整型数组

设置适配器#

listView.setAdapter(simpleAdapter);

运行界面#

image.png

代码#

ListViewActivity#

package com.yt.class3.ListView;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

import androidx.annotation.Nullable;

import com.yt.class3.R;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ListViewActivity2 extends Activity {
    //声明变量
    private ListView listView;
    //数据
    String[] addrs = {"归属地1","归属地2","归属地3","归属地4","归属地5","归属地6"};
    String[] tels = {"手机号1","手机号2","手机号3","手机号4","手机号5","手机号6",};

    //数组列表
    ArrayList<Map<String,Object>> mData =new ArrayList<>();

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listview);
        initView();

    }

    private void initView() {
        //绑定控件
        listView = findViewById(R.id.lv_lv_lv);
        //将数据放在Arraylist里(看作是一个二维表)中去
        //当需要加载多条相同结构的数据时必须要用到循环——for语句
        for(int i=0;i<tels.length;i++){
            //首先就声明Map类型的对象,并进行实例化操作——对应一行的操作
            Map<String,Object> map = new HashMap<>();
            //将数据压入Map中
            map.put("tel",tels[i]);
            map.put("addr",addrs[i]);
            //将map中存放的一行的数据存入二维表格中去
            mData.add(map);

        }
        //创建适配器
        //参数1:上下文关系——getApplicationContext()
        //参数2:数据——List<? extends Map<String,Object>>
        //参数3:布局——使用系统提供的固定的布局
        //参数4:数据从哪里来?——每一行数据存放过程中使用的key,构成了一个字符串数组,必须和存放数据的key完全一致
        //参数5:数据存到哪个控件上去?——固定布局中的2个TextView控件对应的id,构成了一个整型数组
        SimpleAdapter simpleAdapter = new SimpleAdapter(
                getApplicationContext(),
                mData,
                android.R.layout.simple_list_item_2,
                new String[]{"tel","addr"},
                new int[]{android.R.id.text1,android.R.id.text2}
        );
        listView.setAdapter(simpleAdapter);
    }

}

activity_listview.xml#

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="食物:"
        android:gravity="center"
        android:textSize="50dp"
        android:layout_marginBottom="50dp"/>
    <ListView
        android:id="@+id/lv_lv_lv"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:listSelector="@drawable/list_item"
        android:divider="@color/grey2"
        android:dividerHeight="5dp"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="购买"/>

</androidx.appcompat.widget.LinearLayoutCompat>

补一下适配器的分类:

ArrayAdapter:ArrayAdapter 用于将数组或列表中的数据与 ListView 绑定。这是最常用于简单数据列表的适配器类型。 BaseAdapter:BaseAdapter 是一个抽象基类,用于创建自定义适配器。你可以根据自己的需求继承 BaseAdapter 并实现各种方法,以构建更复杂的适配器。 CursorAdapter:CursorAdapter 用于与数据库中的数据关联,通常与 ListView 或 RecyclerView 一起使用。它可以处理 Cursor 对象的数据,并将其显示在视图中。 SimpleCursorAdapter:SimpleCursorAdapter 是 CursorAdapter 的一个实现,它可以简化与 Cursor 和数据库数据的交互,特别适用于 SQLite 数据库。 RecyclerView.Adapter:RecyclerView.Adapter 用于与 RecyclerView 一起工作,提供了更灵活和高性能的列表和网格视图的实现。你可以自定义 RecyclerView.Adapter 来控制数据和视图的呈现。 PagerAdapter:PagerAdapter 用于与 ViewPager 结合使用,用于创建可滑动的视图页(如轮播图)。 FragmentPagerAdapter 和 FragmentStatePagerAdapter:这两种适配器也用于与 ViewPager 结合使用,但它们是为了管理 Fragment 页面的适配器。FragmentStatePagerAdapter 适用于大量页面,因为它支持页面的懒加载和回收。 SimpleAdapter:SimpleAdapter 用于将数据与 ListView 绑定,类似于 ArrayAdapter,但提供了更多的灵活性,可用于自定义数据与视图的映射。

这一期我们要完成使用ListView搭建一个简单的CSGO饰品交易平台的界面


界面预览#

image.png

创建ListView列表布局#

这里用到了LinerLayout,套了一个ListView控件 代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <ListView
            android:id="@+id/lv_listview_showdata"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

ListView列表项布局#

最左边图片,右边LinearLayout里套两个TextViewLinearLayoutorientation属性设为vertical image.png 代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <ImageView
        android:id="@+id/iv_lv_pic"
        android:layout_width="150dp"
        android:layout_height="100dp"
        android:layout_marginTop="30dp"
        />
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="10dp"
        >
        <TextView
            android:id="@+id/tv_lv2_des"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/black"
            android:textSize="15dp"
            android:layout_marginTop="10dp"
            android:text="TextView"
            />
        <TextView
            android:id="@+id/tv_lv2_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/orange2"
            android:textStyle="bold"
            android:textSize="20dp"
            android:layout_marginTop="5dp"
            android:text="TextView"/>
    </LinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>

Activity的编写#

继承父类#

public class ListViewBuffActivity extends AppCompatActivity

覆写OnCreate & 设置活动布局 & 初始化视图#

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_listview2);
        initView();
    }

声明和初始化变量#

素材随便找的CSGO皮肤图片

int[] images = {R.drawable.ic_buff1, R.drawable.ic_buff2, R.drawable.ic_buff3,
            R.drawable.ic_buff4, R.drawable.ic_buff5, R.drawable.ic_buff6};
    String[] des = {
            "爪子刀(★) | 多普勒 (崭新出厂)\n" +
                    "匕首\n" +
                    " 名称标签:“顶级无斑T1 #420”\n" +
                    "图案模板(paint seed): 420\n" +
                    "皮肤编号(paint index): 416 (蓝宝石)\n" +
                    "磨损: 0.009646142832934856\n" +
                    "BUFF磨损排名: 113 (蓝宝石)",

            "短剑(★) | 表面淬火 (略有磨损)\n" +
                    "匕首\n" +
                    "图案模板(paint seed): 612\n" +
                    "皮肤编号(paint index): 44\n" +
                    "磨损: 0.09753446280956268\n" +
                    "BUFF磨损排名: 383",

            "爪子刀(★) | 伽玛多普勒 (崭新出厂)\n" +
                    "匕首\n" +
                    "图案模板(paint seed): 97\n" +
                    "皮肤编号(paint index): 570 (Phase2)\n" +
                    "磨损: 0.0094314469024539\n" +
                    "BUFF磨损排名: 290 (Phase2)",

            "骷髅匕首(★) | 表面淬火 (略有磨损)\n" +
                    "匕首\n" +
                    "图案模板(paint seed): 383\n" +
                    "皮肤编号(paint index): 44\n" +
                    "磨损: 0.08893027156591415\n" +
                    "BUFF磨损排名: 298",

            "M9 刺刀(★) | 伽玛多普勒 (崭新出厂)\n" +
                    "匕首\n" +
                    "图案模板(paint seed): 152\n" +
                    "皮肤编号(paint index): 568 (绿宝石)\n" +
                    "磨损: 0.01418947335332632\n" +
                    "BUFF磨损排名: 186 (绿宝石)",

            "蝴蝶刀(★) | 多普勒 (崭新出厂)\n" +
                    "匕首\n" +
                    "图案模板(paint seed): 878\n" +
                    "皮肤编号(paint index): 618 (Phase2)\n" +
                    "磨损: 0.06081444025039673"
    };
    String[] prices = {"¥ 95880", "¥ 16500", "¥ 22222", "¥ 47000", "¥ 127000", "¥ 23085"};

创建数据列表&实例化ListView#

String[] prices = {"¥ 95880", "¥ 16500", "¥ 22222", "¥ 47000", "¥ 127000", "¥ 23085"};
ListView listView;

绑定控件#

listView = findViewById(R.id.lv_listview_showdata);

将数据放入Arraylist#

这里使用for循环

for (int i = 0; i < images.length; i++) {
            //使用map完成行数据的存储(1、申请空间2、存入数据)
            Map<String, Object> map = new HashMap<>();
            //存入数据是以key-value形式存放数据,类型String,
            map.put("imgs", images[i]);
            map.put("deps", des[i]);
            map.put("prics", prices[i]);
            mData.add(map);
        }

实例化适配器#

ListView2Adapter listView2Adapter = new ListView2Adapter(getApplicationContext(), mData);

设置适配器#

listView.setAdapter(listView2Adapter);

创建自定义适配器#

package com.yt.class3;

import android.content.ComponentName;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.NumberPicker;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Map;

public class ListView2Adapter extends BaseAdapter {
    //内部数据集
    Context mContext;
    //构造函数(只有修饰词,无返回值)在实例化前构造函数时完成实参(上下文关系,数据集)的传入
    //形参: Context context………用来接收实参
    //形参是局部变量,只在当前这个构造函数中有效
    ArrayList<Map<String,Object>> mList;
    public ListView2Adapter(Context context , ArrayList<Map<String,Object>> list) {
        this.mContext = context;
        this.mList = list;
    }

    @Override
    public int getCount() {
        //获取数据集的个数
        return mList.size();
    }

    @Override
    public Object getItem(int position) {
        //获取数据行数据项——每一行的记录
        return mList.get(position);
    }

    @Override
    public long getItemId(int position) {
        //获取数据集某一行的值
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup viewGroup) {
        //声明一个ViewHolder对象
        ViewHolder vh;
        //如果视图是第一次加载,从未打开过
        if(convertView == null){
            //将未知的页面加载,转换成View类型然后赋值给ConvertView
            convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_listview2_item,null);
            //实例化vh
            vh =new ViewHolder();
            vh.ivPic = convertView.findViewById(R.id.iv_lv_pic);
            vh.tvDes = convertView.findViewById(R.id.tv_lv2_des);
            vh.tvPrice = convertView.findViewById(R.id.tv_lv2_price);

            //将vh存入缓存,以备视图再次加载时获取
            convertView.setTag(vh);
        }
        //如果视图不是第一次加载,之前打开过
        else {
            vh = (ViewHolder) convertView.getTag();
        }

        //设置数据
        vh.ivPic.setBackgroundResource((Integer) mList.get(position).get("imgs"));
        vh.tvDes.setText(mList.get(position).get("deps").toString());
        vh.tvPrice.setText(mList.get(position).get("prics").toString());
        return convertView;
    }
    //创建每一行的类ViewHolder
    class ViewHolder{
        ImageView ivPic;
        TextView tvDes,tvPrice;
    }
}

Android学习笔记——ListView列表
https://blog.ytmc.fun/posts/android学习笔记listview列表
作者
yitong
发布于
2023-10-17
许可协议
CC BY-NC-SA 4.0