界面搭建的三个必备属性
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);
运行界面
代码
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饰品交易平台的界面
界面预览
创建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
里套两个TextView
,LinearLayout
的orientation
属性设为vertical
代码:
<?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;
}
}