Android中ListView的使用
1、主要概念
ListView用于将大数据集以列表的形式展示。
ListView可以看成一个容器,它有如下继承链:
View <- ViewGroup <- AdapterView <- AbsListView <- ListView
可见 ListView继承自AdapterView, 而AdapterView的作用就是为ListView提供数据。
主要的API:
listView.setAdapter(adapter实例)
我们通常用的Adapter有如下几个:BaseAdapter, CursorAdapter, ArrayAdapter, SimpleAdapter.它们有如下的继承关系:
Adapter <- ListAdapter <- BaseAdapter
SimpleAdapter、CursorAdapter和ArrayAdapter都是BaseAdapter的子类。
2、使用方法
- 在
Activity布局文件中加入一个ListView组件
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="@array/listItems"></ListView>
这里entries用于指定一个数组来渲染ListView,它定义在strings.xml中,内容如下:
<resources>
<string-array name="listItems">
<item>orange</item>
<item>apple</item>
<item>banana</item>
<item>pear</item>
<item>watermelon</item>
<item>lemon</item>
<item>peach</item>
<item>strawberry</item>
</string-array>
</resources>
到这里,运行项目已经可以看到列表项了。但这种方式只是静态的给ListView添加数据,有很大的局限性。基本不用。下面通过给ListView设置Adapter提供数据。
- 删除上面的
entries属性, 修改Activity的内容
public class ArrayAdapterActivity extends AppCompatActivity {
private String[] items = new String[]{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_array_adapter);
ListView lv = findViewById(R.id.array_adapter_list_view);
//可以这里为ListView设置了一个Adapter
//并且指定了一个array_adapter_list_item.xml的布局文件,因此要新建一个这样的布局文件
//这个布局文件限制了一个数据项的显示形式,即一行数据如何展示
//该布局文件的根标签为TextView
//然后用上面的定义的字符串数组填充每一个TextView
lv.setAdapter(new ArrayAdapter<>(this, R.layout.array_adapter_list_item, items));
}
}
这样,运行程序ListView显示的便是数组中定义的值了。
- 不同的
Adapter使用方式基本一致
下面是SimpleAdapter的使用:
lv.setAdapter(new SimpleAdapter(context, data, resource, from, to));
1.context: 当前上下文
2.data: List<Map<String, ?>>类型的数据集
3.resource:单个数据项的布局文件
5.from:data中map的各个key
6.to: 将key对应的值映射到数据项布局文件的某个组件
看个例子:
public class SimpleAdapterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_adapter);
ListView lv = findViewById(R.id.simple_adapter_list_view);
Map<String, Object> student1 = new HashMap<>();
student1.put("username", "jack");
student1.put("gender", "male");
student1.put("age", 33);
Map<String, Object> student2 = new HashMap<>();
student2.put("username", "nacy");
student2.put("gender", "female");
student2.put("age", 13);
List<Map<String, Object>> students = new ArrayList<>();
students.add(student1);
students.add(student2);
//from对应map的key
String[] from = new String[]{"username", "gender", "age"};
//to对应单行数据项布局文件中组件的id
int[] to = new int[]{R.id.simple_adapter_username, R.id.simple_adapter_gender, R.id.simple_adapter_age};
lv.setAdapter(new SimpleAdapter(this, students, R.layout.simple_adapter_list_item, from, to));
}
}
单行数据项布局文件:
<?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="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/simple_adapter_username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"></TextView>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="@+id/simple_adapter_gender"
android:layout_width="match_parent"
android:layout_height="wrap_content"></TextView>
<TextView
android:id="@+id/simple_adapter_age"
android:layout_width="match_parent"
android:layout_height="wrap_content"></TextView>
</LinearLayout>
</LinearLayout>
3、BaseAdapter的使用
BaseAdapter作为一个抽象类,比前几种Adapter使用起来更灵活。
下面是一个例子:
创建一个类继承BaseAdapter
public class MyBaseAdapter extends BaseAdapter {
//根据当前上下文将一个布局文件加载到内存,实例化为对象的一个类
private LayoutInflater layoutInflater;
public MyBaseAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
}
//决定数据项的个数
@Override
public int getCount() {
return 20;
}
//指定位置的数据项
@Override
public Object getItem(int position) {
return null;
}
//指定位置数据项的索引
@Override
public long getItemId(int position) {
return 0;
}
//容纳当前数据项布局文件的一个类
private class ViewHolder {
public ImageView header;
public TextView username;
}
//手机在滚动屏幕时,超出屏幕之外的ViewItem要被移除
//如果有10000个ViewItem,那么getView方法就要调用10000次,加载布局文件10000次,然后创建ViewItem,这是相当耗资源的
//为了提高性能,就需要对移除的ViewItem进行复用,每次滚动屏幕移除的ViewItem就是convertView
//因此每次调用方法时,都要对convertView判空,如果为空才去加载布局文件,创建新的View,否则进行复用。
//这里的ViewHolder相当于一个容器,承载了一个ViewItem中所有的组件,避免了每次都要findViewById
//一次findViewById之后,通过setTag方法将其设置到convertView中,下次就不用再查找了
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.base_adapter_list_item, null);
holder = new ViewHolder();
holder.header = convertView.findViewById(R.id.iv_header);
holder.username = convertView.findViewById(R.id.tv_username);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.header.setImageResource(R.drawable.ic_launcher_foreground);
holder.username.setText("这是第" + position + "项");
return convertView;
}
}
数据项布局文件:
<?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="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#008080"></ImageView>
<TextView
android:id="@+id/tv_username"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"></TextView>
</LinearLayout>
Activity文件
public class BaseAdapterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_adapter);
ListView lv = findViewById(R.id.base_adapter_list_view);
lv.setAdapter(new MyBaseAdapter(this));
lv.setOnItemClickListener(new ListView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(BaseAdapterActivity.this, "点击" + position, Toast.LENGTH_SHORT).show();
}
});
lv.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(BaseAdapterActivity.this, "长按" + position, Toast.LENGTH_SHORT).show();
return true;
}
});
}
}
Android中ListView的使用的更多相关文章
- Android中Listview点击item不变颜色以及设置listselector 无效
Android中Listview点击item不变颜色以及设置listselector 无效 这是同一个问题,Listview中点击item是会变颜色的,因为listview设置了默认的listsele ...
- Android中ListView控件的使用
Android中ListView控件的使用 ListView展示数据的原理 在Android中,其实ListView就相当于web中的jsp,Adapter是适配器,它就相当于web中的Servlet ...
- android中ListView控件&&onItemClick事件中获取listView传递的数据
http://blog.csdn.net/aben_2005/article/details/6592205 本文转载自:android中ListView控件&&onItemClick ...
- android中ListView点击和里边按钮点击不能同时生效问题解决
今天遇到一个问题:android中ListView点击和里边button点击不能同时生效问题解决. 原因是: listView 在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得 ...
- Android中ListView无法点击
Android中ListView无法点击 转自:http://xqjay19910131-yahoo-cn.iteye.com/blog/1319502 问题描述: ListView中Item加入 ...
- Android中ListView实现图文并列并且自定义分割线(完善仿微信APP)
昨天的(今天凌晨)的博文<Android中Fragment和ViewPager那点事儿>中,我们通过使用Fragment和ViewPager模仿实现了微信的布局框架.今天我们来通过使用Li ...
- Android中ListView的几种常见的优化方法
Android中的ListView应该算是布局中几种最常用的组件之一了,使用也十分方便,下面将介绍ListView几种比较常见的优化方法: 首先我们给出一个没有任何优化的Listview的Adapte ...
- Android中ListView动态加载数据
1. 引言: 为了提高ListView的效率和应用程序的性能,在Android应用程序中不应该一次性加载ListView所要显示的全部信息,而是采取分批加载策略,随着用户的滑动,动态的从后台加载所需的 ...
- Android中ListView异步加载图片错位、重复、闪烁问题分析及解决方案
我们在使用ListView异步加载图片的时候,在快速滑动或者网络不好的情况下,会出现图片错位.重复.闪烁等问题,其实这些问题总结起来就是一个问题,我们需要对这些问题进行ListView的优化. 比如L ...
- Android中ListView 控件与 Adapter 适配器如何使用?
一个android应用的成功与否,其界面设计至关重要.为了更好的进行android ui设计,我们常常需要借助一些控件和适配器.今天小编在android培训网站上搜罗了一些有关ListView 控件与 ...
随机推荐
- Ionic4.x 内置颜色
primary/secondary/tertiary /success/warning/danger/dark/medium/light
- throws和throw的使用
throws 用在方法定义上 后面跟一个或者多个异常名称 如果是多个异常名称,之间使用","隔开 , 表达的意思是给该方法添加一个或者多个异常声明; 告诉调用者该方法可能会出现问题 ...
- WPF窗体应用程序开发
1.Window:登录窗口.主窗体.消息框 2.UserControl:业务界面.消息框(如果使用UC来实现,则需要做特殊的处理,比如中断功能如何处理?)(显示一个UC,必须将其添加到容器中,所以&l ...
- 为何有DAO与Service层?为何先搞Dao接口在搞DaoImpl实现?直接用不行吗?
转自 http://blog.sina.com.cn/s/blog_4b1452dd0102wvox.html 我们都知道有了Hibernate后,单独对数据的POJO封装以及XML文件要耗损掉一个类 ...
- WordPress获取特色图像的链接地址
为什么要获取WordPress的特色图像呢? 这主要是因为,我们已经写好了静态模板文件,只有获取WordPress特色图像地址插入进去就可以了,非常方便. 还有就是有的时候,我们需要设置图片的宽度为1 ...
- Django面试题(附带答案)
总结的一些Django中会问的问题,希望对你们有用. 1. Django的生命周期 当用户在浏览器输入url时,浏览器会生成请求头和请求体发送给服务端,url经过Django中的wsgi时请求对象创建 ...
- C/C++查漏补缺(常更)
一.#define宏定义 如下程序段,则输出结果为: #define MAX 12 int main(){ cout << "20\0MAX019" << ...
- 【计算机视觉】OpenCV读取视频获取时间戳等信息(PS:经测试并不是时间戳,与FFMPEG时间戳不一样)
OpenCV中通过VideoCaptrue类对视频进行读取操作以及调用摄像头,下面是该类的API. 1.VideoCapture类的构造函数: C++: VideoCapture::VideoCapt ...
- C/C++.控制台输入(cin/getchar)
1.类似的函数有:cin.getchar.fgetc 等 2.问题: 最后的"\n"都不取出来... 2.1.对策:(ZC:下面是 我自己使用后的感受) (1)fflush(std ...
- Android_7.1.1_r6源码编译
上篇文章讲述了如何下载Android源码,在篇文章就来说一说Android源码编译.其实一般来说如果修改的软件和底层没什么关系,直接提取相应的源代码到Android Studio编译就可以了,如果是与 ...