Android Studio 之 BaseAdapter 学习笔记
•前行必备——ListView的显示与缓存机制
我们知道 ListView、GridView 等控件可以展示大量的数据信息。
假如下图中的 ListView 可以展示 100 条信息,但是屏幕的尺寸是有限的,只能显示下图中的 7 条。
当向上滑动 ListView 的时候,item1 被滑出了屏幕区域,那么系统就会将item1回收到Recycler中,即View缓冲池中;
而将要显示的 item8 则会从缓存池中取出布局文件,并重新设置好 item8 需要显示的数据,并放入需要显示的位置。
这就是ListView的缓冲机制,总结起来就是一句话:需要时才显示,显示完就被会收到缓存。
ListView,GridView 等数据显示控件通过这种缓存机制可以极大的节省系统资源。
示意图如下:
•步入主提——BaseAdapter
使用 BaseAdapter 比较简单,主要是通过继承此类来实现 BaseAdapter 的四个方法:
- public int getCount() : 适配器中数据集的数据个数;
- public Object getItem(int position) : 获取数据集中与索引对应的数据项;
- public long getItemId(int position) : 获取指定行对应的ID;
- public View getView(int position,View convertView,ViewGroup parent) : 获取每一行 Item 的显示内容。
下面通过一个简单示例演示如何使用BaseAdapter。
准备工作
新建一个项目,选择 Empty Activity 选项;
Android Studio 会自动为我们生成两个文件 MainActivity.java 和 activity_main.xml;
activity_main.xml
<?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"> <ListView
android:id="@+id/lv_base_adapter"
android:layout_width="match_parent"
android:layout_height="match_parent"
/> </RelativeLayout>在 res/layout 新建一个 base_adapter_item.xml 文件;
base_adapter_item.xml
<?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:padding="10dp"
android:orientation="horizontal"> <ImageView
android:id="@+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="160dp"
android:orientation="vertical"
android:layout_marginLeft="10dp"> <TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:gravity="left"/>
<TextView
android:id="@+id/desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:gravity="left"/>
</LinearLayout>
</LinearLayout>页面布局说明
- 整体采用线性布局,并以水平排列。
- 左边第一项定义一个ImageView组件,用来显示图片。
- 右边嵌套一个线性布局,并以垂直排列。
- 嵌套的线性布局里面定义了两个TextView,一个显示名字,一个显示介绍。
base_adapter_item布局示意图如下:
新建 Fruit 类;
Fruit.java
public class Fruit {
private String name;//名称
private String desc;//描述
private int imgId;//对应图片id public Fruit(String name,String desc,int imgId){
this.name = name;
this.desc = desc;
this.imgId = imgId;
} public String getDesc() {
return desc;
} public String getName() {
return name;
} public int getImgId() {
return imgId;
}
}通过此 Fruit类,我们就将要显示的数据与 ListView 的布局内容(base_adapter_item)一一对应了;
每个 Fruit 对象对应 ListView 的一条数据,这种方法在 ListView 中使用的非常广泛。
接下来需要创建一个自定义的适配器,这个适配器继承自 BaseAdapter,并将 List 的泛型指定为 Fruit 类。
新建 MyBaseAdapter 类;
MyBaseAdapter.java
public class MyBaseAdapter extends BaseAdapter { private List<Fruit> list;//数据源
private Context context;//调用 MyBaseAdapter 的上下文对象 //通过构造方法将数据源与数据适配器关联起来
public MyBaseAdapter(Context context,List<Fruit>list){
this.context = context;
this.list = list;
}
@Override
//ListView需要显示的数据数量
public int getCount() {
return list.size();
} @Override
//指定的索引对应的数据项
public Object getItem(int position) {
return list.get(position);
} @Override
public long getItemId(int position) {
return position;
} static class ViewHolder{
private ImageView imgView;
private TextView name;
private TextView desc;
}
@Override
//返回每一项的显示内容
public View getView(int position, View convertView, ViewGroup parent) { View view;
ViewHolder holder; if(convertView == null){
//由于我们只需要将 fruit.XML 转化为 View,并不涉及到具体的布局
// 所以第二个参数通常设置为null
view = LayoutInflater.from(context).inflate(R.layout.base_adapter_item, null);
holder = new ViewHolder();
holder.imgView = view.findViewById(R.id.header);
holder.name = view.findViewById(R.id.name);
holder.desc = view.findViewById(R.id.desc); view.setTag(holder);
}else{
view = convertView;
holder = (ViewHolder) view.getTag();
} //获取第 position 项的数据
Fruit fruit = list.get(position);
holder.imgView.setImageResource(fruit.getImgId());
holder.name.setText(fruit.getName());
holder.desc.setText(fruit.getDesc()); return view;
}
}MyBaseAdapter代码分析
listView在开始绘制的时候,系统首先调用 getCount() 函数,根据他的返回值得到 ListView 的长度。
然后根据这个长度,调用 getView() 逐一绘制每一行,如果你的 getCount() 返回值是 0 的话,列表将不显示,同样 return 1,就只显示一行。
系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器),当手动完成适配时,必须手动映射数据,这需要重写 getView() 方法。
系统在绘制列表的每一行的时候将调用此方法。
getView() 有三个参数:
- position表示将显示的是第几行
- covertView是从布局文件中 inflate 来的布局
我们用LayoutInflater的方法将定义好的 base_adapter_item 文件提取成 View 实例用来显示。
通过 view.findViewById() 找到布局文件中的控件;
实例化 Fruit 类,通过 set 方法将数据对应到各个组件上;
至此一个自定义的 listView 就完成了,现在让我们回过头从新审视这个过程。
系统要绘制 ListView,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?
调用 getView() 函数,在这个函数里面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。
好了,绘制完这一行了,那再绘制下一行,直到绘完为止。
PS : 有关 ViewHolder 的使用,参考我的这篇博客——提升ListView的运行效率。
接下来,也是最后一步,修改 MainActivity.java 中的代码;
MainActivity.java
public class TestBaseAdapterActivity extends AppCompatActivity { private ListView mLv;
private MyBaseAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_base_adapter); mLv = findViewById(R.id.lv_base_adapter);
adapter = new MyBaseAdapter(TestBaseAdapterActivity.this,getData());
mLv.setAdapter(adapter);
} private List<Fruit> getData(){
List<Fruit> list = new ArrayList<>(); //String name,String desc,int imgId
list.add(new Fruit("apple","苹果",R.drawable.apple));
list.add(new Fruit("banana","香蕉", R.drawable.banana));
list.add(new Fruit("oranges","橘子",R.drawable.oranges)); return list;
}
}apple,banana,oranges 是我从网上下载的图片,放置在了 drawable 文件夹下:
![]()
![]()
•运行结果
Android Studio 之 BaseAdapter 学习笔记的更多相关文章
- Android Studio调试方法学习笔记
(注:本人所用Android Studio的Keymap已设为Eclipse copy) 1.设置断点 只有设置断点,才好定位要调试什么地方,否则找不到要调试的地方,无法调试.(调试过程中也可以增加断 ...
- Android Studio 之 ImageView 学习笔记
•参考资料 [1]:菜鸟教程 [2]:bilibili视频教程 •src和blackground的区别 background通常指的都是背景,而src指的是内容 当使用 src 填入图片时,是按照图片 ...
- Android(java)学习笔记206:利用开源SmartImageView优化网易新闻RSS客户端
1.我们自己编写的SmartImageView会有很多漏洞,但是我们幸运的可以在网上利用开源项目的,开源项目中有很多成熟的代码,比如SmartImageView都编写的很成熟的 国内我们经常用到htt ...
- Android(java)学习笔记205:网易新闻RSS客户端应用编写逻辑过程
1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,bl ...
- Android(java)学习笔记149:利用开源SmartImageView优化网易新闻RSS客户端
1.我们自己编写的SmartImageView会有很多漏洞,但是我们幸运的可以在网上利用开源项目的,开源项目中有很多成熟的代码,比如SmartImageView都编写的很成熟的 国内我们经常用到htt ...
- Android(java)学习笔记148:网易新闻RSS客户端应用编写逻辑过程
1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,bl ...
- Android自动化测试之Monkeyrunner学习笔记(一)
Android自动化测试之Monkeyrunner学习笔记(一) 因项目需要,开始研究Android自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括Monkey.Monkeyr ...
- Android(java)学习笔记267:Android线程池形态
1. 线程池简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...
- Android(java)学习笔记207:开源项目使用之gif view
1. 由于android没有自带的gif动画,我在Android(java)学习笔记198:Android下的帧动画(Drawable Animation) 播客中提到可以使用AnimationVie ...
随机推荐
- YouTube 视频下载工具
YouTube 视频下载工具 我不生产视频,只是优秀视频的搬运工! YouTube-dl https://github.com/search?q=youtube-dl https://github.c ...
- 在线可视化设计网站 & 在线编辑器
在线可视化设计网站 在线编辑器:海报编辑器.H5 编辑器.视频编辑器.音频编辑器.抠图编辑器 在线 拖拽 可视化 编辑器 Canvas WebGL Canva With Canva, anyone c ...
- 如何用 js 实现一个 call 函数
如何用 js 实现一个 call 函数 原理 实现方式 总结 refs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referenc ...
- node cli & emoji
node cli & emoji cli $ yarn add node-emoji $ npm i node-emoji https://github.com/omnidan/node-em ...
- qrcode & console.log
qrcode & console.log image https://fs-api.lightyy.com/service/utils/qrcode?url=http://169.254.13 ...
- 小程序 web-view
小程序 web-view https://opendocs.alipay.com/mini/component/web-view https://opendocs.alipay.com/mini/ap ...
- Flutter Android Toast Message(flutter访问Android Toast Message)
原文 Android Toast通知可用于向用户发送快速消息,并在几秒钟后消失. 但是当涉及Flutter时,没有直接的方式来显示这些Toast消息.因此,我们需要找到一种替代方法来实现它.在这种情况 ...
- 高倍币VAST,如何破局NGK算力市场?
2020年,全球经济危机的爆发,无疑是给全球经济蒙上了一层阴影.而世界主要经济体也开启了无节制的放水,通过一轮又一轮的宽松货币政策,以刺激经济的发展.然而宽松的货币政策也加速了以美元为首的货币贬值,同 ...
- 揭秘高倍矿币 Baccarat BGV,为何NGK DeFi的财富效应如此神奇?
作为区块链4.0代表的NGK公链,这次也将借助它自己的DeFi版块NGK Baccarat,开启属于它自己的千倍财富之旅. 如果说,比特币能让没有银行账户的人,可以在全球任何时间.地点都能自由进行交易 ...
- openwrt编译加载龙尚U9300模组上网
硬件平台:MT7628A openwrt版本:MTK_SDK 1.添加模组信息 /build_dir/target-mipsel_24kc_musl/linux-ramips_mt76x8/linux ...



