ListView简介
ListView介绍
在Android开发中,ListView是一个比较常用的控件。它以列表的形式展示具体数据内容,并且能够根据数据的长度自适应屏幕显示。
ListView控件的使用
新建Android工程。
在activity_main.xml中加入ListView控件
1
2
3
4
5 <ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
常用数据适配器(Adapter)
在使用ListView时需要对其进行数据适配。为了实现这个功能,Android系统提供一系列的适配器(Adapter)对ListView进行数据适配。
适配器就像显示器,把复杂的数据按人们易于接受的方式来展示。
BaseAdapter
即基本的适配器。它实际上就是一个抽象类,该类拥有四个抽象方法。在Android开发中,就是根据这几个抽象方法来对ListView进行数据适配的
SimpleAdapter
SimpleAdapter继承自BaseAdapter,实现了BaseAdapter的四个抽象方法,分别是getCount()、getItem()、getItemId()、getView()方法。
ArrayAdapter
ArrayAdapter也继承自BaseAdapter,与SimpleAdapter相同。ArrayAdapter通常用于适配TextView控件,例如Android系统中的设置菜单(Setting)。
BaseAdapter适配器
BaseAdapter是使用得比较多,适用于ListView、GridView、Spinner等控件适配器,通过重写getView方法,展示自定义视图。
掌握BaseAdater的四个抽象方法:getItem(int),getItemId(int),getCount(),getView(int,View,ViewGroup)
使用convertView,ViewHolder 优化ListView
案例: 个人通讯录列表
自定义布局,用来显示listView的列表单项。
自定义BaseAdapter适配器。
绑定绑定数据适配器
运行通讯录
UI布局设计
1 |
|
自定义适配器BaseAdapter
a. 自定义model类Person(数据对象)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package com.example.timeemail.entity;
public class Person {
private String name;
private int img;
public Person() {
}
public Person(String name, int img) {
this.name = name;
this.img = img;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
}b. 自定义PersonAdapter适配器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 package com.example.timeemail.adapter;
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.TextView;
import com.example.timeemail.R;
import com.example.timeemail.entity.Person;
import java.util.ArrayList;
import java.util.List;
public class PersonAdapter extends BaseAdapter {
private List<Person> pdata = new ArrayList<Person>();
private Context context;
public PersonAdapter(List<Person> pdata, Context context) {
this.pdata = pdata;
this.context = context;
}
public int getCount() {
return pdata.size();
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return position;
}
//优化ListView
//定义一个ViewHolder静态类
static class ViewHolder{
//定义属性,对应是列表项数据
public ImageView myimg;
public TextView myname;
}
public View getView(int position, View convertView, ViewGroup parent) {
//定义ViewHolder对象
ViewHolder holder;
//判断convertView是否为空,convertView对应的列表项
if (convertView==null){
//新建
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.driftitem,parent,false);
holder.myimg = (ImageView) convertView.findViewById(R.id.item_img);
holder.myname = (TextView) convertView.findViewById(R.id.item_name);
convertView.setTag(holder);
}else{
//复用列表项
holder = (ViewHolder) convertView.getTag();
}
//设置列表项数据
holder.myimg.setImageResource(pdata.get(position).getImg());
holder.myname.setText(pdata.get(position).getName());
return convertView;
}
}
绑定数据适配器
1 | package com.example.timeemail; |
ListView的使用
ListView的常用监听事件
OnItemClickListener 处理视图中单个条目的点击事件
OnItemLongClickListener 处理视图中单个条目的长按事件
OnScrollListener 监视滚动的变换,常用于视图在滚动中加载数据
为通讯录加入点击事件
实现OnItemClickListener监听。
1 | public class DriftActivity extends AppCompatActivity implements AdapterView.OnItemClickListener |
实现onItemClick方法。
1 | //实现点击方法 |
为通讯录加入滚动事件
实现OnScrollListener 监听。
1 | public class DriftActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AbsListView.OnScrollListener |
实现onScroll,onScrollStateChanged方法。
滚动停止后,增加一条通讯录数据。
1 | //实现滚动方法 |
RecyclerView简介
RecyclerView介绍
RecyclerView 是一个增强版的ListView
Android 5.0推出的,是support-v7包中的新组件(最低兼容到android 3.0版本)。
RecyclerView,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration , ItemAnimator实现令人瞠目的效果。
RecyclerView相对于ListView的优点
1、可以使用布局管理器LayoutManager来管理RecyclerView的显示方式:水平、垂直、网络、网格交错布局;
2、自定义item的分割条,实现自定义;
3、可以控制item的添加和删除的动画,非常自由,可以自定义动画,配合具体场景,效果非常棒;
4、可以动态的在指定位置添加和删除某一项,而列表不会回到顶部,动态的update列表数据;
5、缺点:就是没有OnItemClickListenter(),需要自己在RecycleView内部自定义列表项的点击事件或则长按事件;
6、在Material Design中和CardView配合使用,显示效果非常突出。
案例: 个人通讯录列表(二)
自定义布局,用RecyclerView显示通讯录。
通过RecyclerView.Adapter适配器。
RecyclerView绑定绑定数据适配器
运行通讯录
通讯录UI布局设计
a. 定义主布局文件,采用RecyclerView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/register_bg"
tools:context=".DriftActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDrift"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>b. 复用布局文件Driftitem.xml,图文结构显示。
自定义适配器RecyclerView.Adapter
a. 复用model类Person(数据对象)。
b. 自定义RecyclerView.Adapter适配器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 package com.example.timeemail.adapter;
import android.content.Context;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.timeemail.R;
import com.example.timeemail.entity.Person;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.List;
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.MyViewHolder>{
private List<Person> pdata = new ArrayList<Person>();
private Context context;
public MyRecyclerAdapter(List<Person> pdata, Context context) {
this.pdata = pdata;
this.context = context;
}
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//填充布局,获取列表项布局文件
View itemview = LayoutInflater.from(context).inflate(R.layout.driftitem,parent,false);
MyViewHolder myViewHolder = new MyViewHolder(itemview);
return myViewHolder;
}
//填充onCreateViewHolder方法返回的holder控件
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Person person = pdata.get(position);
holder.myimg.setImageResource(person.getImg());
holder.myname.setText(person.getName());
}
//返回通讯录数据个数
public int getItemCount() {
return pdata.size();
}
class MyViewHolder extends RecyclerView.ViewHolder{
//定义对应列表项
private ImageView myimg;
private TextView myname;
//构造方法
public MyViewHolder(@NonNull View itemView) {
super(itemView);
myimg = (ImageView)itemView.findViewById(R.id.item_img);
myname = (TextView) itemView.findViewById(R.id.item_name);
}
}
}
RecyclerView绑定数据适配器
a. RecyclerView绑定绑定数据适配器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 package com.example.timeemail;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.example.timeemail.adapter.MyRecyclerAdapter;
import com.example.timeemail.adapter.PersonAdapter;
import com.example.timeemail.entity.Person;
import java.util.ArrayList;
import java.util.List;
public class DriftActivity extends AppCompatActivity {
private RecyclerView Rvdrift;
private MyRecyclerAdapter myAdapter;
private String[] names = {"李铭","小花","宋妈","张明","姥爷","表哥"};
private int[] imgs = {R.mipmap.tx1,R.mipmap.tx2,R.mipmap.tx3,
R.mipmap.tx4,R.mipmap.tx5,R.mipmap.tx6};
private List<Person> drift = new ArrayList<Person>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drift);
//初始化数据
initDataBooks();
//1.初始化控件
Rvdrift = findViewById(R.id.rvDrift);
//2.设置RecyclerView布局管理器
Rvdrift.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
//3.初始化数据适配器
myAdapter = new MyRecyclerAdapter(drift,this);
//4.采用默认动画效果
Rvdrift.setItemAnimator(new DefaultItemAnimator());
//5.设置适配器
Rvdrift.setAdapter(myAdapter);
}
//初始化数据
private void initDataBooks(){
for (int i=0;i<names.length;i++){
//新建Person对象,存放头像及姓名
Person person = new Person(names[i],imgs[i]);
//将数据存入数据列表
drift.add(person);
}
}
}
RecyclerView的使用
RecyclerView的OnItemClickListener监听器
没有提供setOnItemClickListener这个回调,也就是无法响应点击事件。
- 定义监听器OnItemClickListener
- Adapter中实现监听器OnItemClickListener
- 绑定监听器
案例:可点击的个人通讯录列表(三)
创建点回调接口:OnItemClickListener。
1
2
3
4
5
6
7
8 package com.example.timeemail.adapter;
import android.view.View;
public interface OnItemClickListener {
public void OnItemClick(View view,int postion);
}
Adapter里设置回调接口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 //定义监听
private OnItemClickListener monItemClickListener;
public void setMonItemClickListener(OnItemClickListener monItemClickListener) {
this.monItemClickListener = monItemClickListener;
}
//填充onCreateViewHolder方法返回的holder控件
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Person person = pdata.get(position);
holder.myimg.setImageResource(person.getImg());
holder.myname.setText(person.getName());
//设置监听方法
if(monItemClickListener != null){
holder.itemView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
monItemClickListener.OnItemClick(holder.itemView,position);
}
});
}
}Activity使用点击回调接口。
1
2
3
4
5
6
7
8
9
10 //6.设置监听器
myAdapter.setMonItemClickListener(new OnItemClickListener() {
public void OnItemClick(View view, int postion) {
//获取调集通讯录的对象
Person person = drift.get(postion);
//弹出提示
Toast.makeText(DriftActivity.this,"您点击了第个通讯录,姓名为"+person.getName(),Toast.LENGTH_LONG).show();
}
});运行通讯录