安卓APP_ 控件(10)—— ListView可上下滑动的列表(重要)与ViewHolder优化

摘自:安卓APP_ 控件(10)—— ListView可上下滑动的列表(重要)与ViewHolder优化
作者:丶PURSUING
发布时间: 2021-04-12 23:28:27
网址:https://blog.csdn.net/weixin_44742824/article/details/115618378

目录

  • 项目运行效果
  • (1)创建ListView
  • (2)创建新的item布局
  • (3)创建 javaBean
  • (4)创建数据中间桥梁:Adapter
  • (5)listView的点击效果
  • 更多细节在代码中体现
  • 重点:优化getView中需要多次调用的 `findViewById`
  • 知识扫盲
    • (1)什么是ViewHolder
    • (2)什么是setTag
    • (3)什么是javaBean

项目运行效果

ListView实现效果一睹为快

在这里插入图片描述

可以进行上下的滑动,也可以对每一个条目进行点击,每个条目称为ListView的item。

(1)创建ListView

在activity_main.xml下创建ListView,默认显示效果如下:
在这里插入图片描述当然,还要对每一个item填充数据,并且每一个item实际上就是一种布局,所以要给item进行布局。

(2)创建新的item布局

根据项目需求进行设置,这里仅用TestView做简单的演示。
在这里插入图片描述

(3)创建 javaBean

设置完以上两个布局后,就要设置数据。ListView数据都是从网上获取的,在item下可能会有好几个数据,所以一般会去创建一个java的Bean类。

使用代码生成器,生成name的设置方法与获取方法
(快捷键为alt+Insert

在这里插入图片描述

(4)创建数据中间桥梁:Adapter

用for循环模拟从网上获取的数据,数据如何填充listview这个对象呢?有个辅助类:Adapter

Adapter(适配器)
Adapter是用来帮助填出数据的中间桥梁,简单点说就是将各种数据以合适的形式显示在View中给用户看。

MainActivity.java中调用了Adapter,如下:
在这里插入图片描述
而Adapter的实现细节还要看下文的“更多细节在代码中体现”。

(5)listView的点击效果

实际上listView给我们提供有监听事件:
在这里插入图片描述

效果如下图

在这里插入图片描述

更多细节在代码中体现

Mainactivity.java

public class MainActivity extends AppCompatActivity {private List<Bean> data = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);for(int i = 0;i< 100;i++){Bean bean = new Bean();bean.setName("zhua"+i);data.add(bean);}//拿到listview的对象ListView listview = findViewById(R.id.lv);//数据如何填充这个对象呢?把数据放到Adapter里面去listview.setAdapter(new myAdapter(data,this));//listview的监听事件listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Override//方法重写,点击后打印positionpublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {Log.e("zhua", "onItemClick: "+position );}});}
}
  • 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

activity_main.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="wrap_content"android:orientation="vertical"><ListViewandroid:id="@+id/lv"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

myAdapter.java

//继承BaseAdapter后实现其方法
public class myAdapter extends BaseAdapter {private List<Bean> data;private Context context;//存放数据,以及把context放进去的构造方法public myAdapter(List<Bean> data, Context context){this.data = data;this.context = context;}@Override//返回listview能够显示多少数据:data有多少显示多少public int getCount() {return data.size();}@Override//获取itempublic Object getItem(int position) {return null;}@Override//获取itemidpublic long getItemId(int position) {return position;}@Override//返回每一个item条目并给它进行一个设值后返回到界面上。//每次在显示的时候,都会调用getview给每一个item进行赋值public View getView(int position, View convertView, ViewGroup parent) {//因为item是可以复用的,上下滑动界面时会不断地进行判断,为了防止convertView不断创建,要进行判断if(convertView == null){//先拿到item条目的布局                             渲染layout.list_item,渲染后给到convertViewconvertView = LayoutInflater.from(context).inflate(R.layout.list_item,parent,false);}//需要把data创建的那些值,传到textView每一个item上面(这个值在项目中是从网上获取的)TextView textView = convertView.findViewById(R.id.tv);//getView并不是只会调用一次,而是界面每显示一个item的时候都会创建一次textView.setText(data.get(position).getName());//这样就把name设置到了textview上面Log.e("zhua", "getView: "+position);return convertView;}}
  • 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

Bean.java

public class Bean {String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

list_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="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/tv"android:textSize="30sp"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

重点:优化getView中需要多次调用的 findViewById

但是上面的使用方法,并不是ListView的最优解,因为在myAdapter.java中,每次调用getView都会间接调用方法findViewByld,这非常耗时,效率不高。
在这里插入图片描述
优化后的myAdapter.java:每次在getView调用的时候就节省了findViewByld的调用时间。

//继承BaseAdapter后实现其方法
public class myAdapter extends BaseAdapter {private List<Bean> data;private Context context;//存放数据,以及把context放进去的构造方法public myAdapter(List<Bean> data, Context context){this.data = data;this.context = context;}@Override//返回listview能够显示多少数据:data有多少显示多少public int getCount() {return data.size();}@Override//获取itempublic Object getItem(int position) {return null;}@Override//获取itemidpublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {//(2)创建viewHolder对象ViewHolder viewHolder;//当convertView为null的时候(首次进入)进行如下设置if(convertView == null){//(3)实例化这个对象viewHolder = new ViewHolder();convertView = LayoutInflater.from(context).inflate(R.layout.list_item,parent,false);//(4)让它去获取findViewById:把TextView放到ViewHolder里面viewHolder.textView = convertView.findViewById(R.id.tv);//(5)再通过setTag把viewHolder放到convertView里面去convertView.setTag(viewHolder);}else{//(6)不是第一次进来不需要进行上面的设置,直接:viewHolder = (ViewHolder) convertView.getTag();//使viewHolder.textView与R.id.tv进行了“绑定”}//(7)再使用textView的时候呢就要通过viewHolderviewHolder.textView.setText(data.get(position).getName());//这样就把name设置到了textview上面Log.e("zhua", "getView: "+position);return convertView;}//(1)创建ViewHolder类private final class ViewHolder{TextView textView;//在item布局中有几个子控件就填充几个}
}
  • 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

其他补充:
在这里插入图片描述

知识扫盲

(1)什么是ViewHolder

ViewHolder通常出现在适配器里,为的是listview滚动的时候快速设置值,而不必每次都重新创建很多对象,从而提升性能。

在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建。

ListView加载数据都是在public View getView(int position, View convertView, ViewGroup parent) {}方法中进行的(要自定义listview都需要重写listadapter:如BaseAdapter,SimpleAdapter,CursorAdapter的等的getvView方法)。

优化listview的加载速度就要让convertView匹配列表类型,并最大程度上的重新使用convertView。 getview的最慢的加载方式是每一次都重新定义一个View载入布局,再加载数据。而最快的方式是定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为null时重新使用即可。

(2)什么是setTag

我们使用View,大多数情况就是为了向用户展示一定的数据,因此,view的使用又总是离不开数据的。基本很多人的做法都会把数据以及view分开,但是其实在Android开发的view中已经有api接口可以完成一定量数据的存储了,这就是——View.setTag()以及View.getTag()

功力不够,应用场景暂时看不懂,先挂着:Android View中setTag的二三事

(3)什么是javaBean

Java语言欠缺属性、事件、多重继承功能。所以,如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java Bean正是编写这套胶水代码的惯用模式或约定。

举例详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何阅读一本书 pdf_如何快速阅读一本书?

/ 01 /阅读的重要性不言而喻。芒格说过&#xff0c;“我见过的聪明人&#xff0c;没有一个不读书的&#xff0c;一个都没有。”但是读什么样的书&#xff1f;如何过目不忘&#xff1f;怎样高效阅读&#xff1f;却是一门学问。大一时我读了500本书&#xff0c;每天在班里讲三本书…

弹性布局----Flex

1.背景 传统的布局方案基于盒状模型,依赖display position float 的方式实现,灵活性较差,对于那些特殊的布局非常不方便. 2009年,W3C提出了一种新的方案--Flex布局. 2.什么是Flex布局? Flex是Flexible Box的缩写,意为"弹性布局",用来为盒模型提供最大的灵活性,以便…

Lab 6:uC/OS II

为什么80%的码农都做不了架构师&#xff1f;>>> 目标&#xff1a; 移植uC/OS II到RPi上&#xff0c;实现两个任务的调度。这两个任务能轮流点亮LED&#xff0c;并通过串口发送消息表明自己正在运行 具体步骤&#xff1a; 助教给的代码已经很完整了&#xff0c;…

安卓APP_ 布局(7) —— ViewPager翻页

摘自&#xff1a;安卓APP_ 布局&#xff08;7) —— ViewPager翻页 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-14 19:37:18 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115705471 ViewPager 实现效果一睹为快&#xff08;1&#…

15个实用的grep示例

2019独角兽企业重金招聘Python工程师标准>>> 首先&#xff0c;新建如下文件demo_file THIS LINE IS THE 1ST UPPER CASE LINE IN THIS FILE. this line is the 1st lower case line in this file. This Line Has All Its First Character Of The Word With Upper C…

IntelliJ IDEA 连接数据库 详细过程

IntelliJ IDEA集成了众多插件&#xff0c;方便开发者使用&#xff0c;使用其自带的Database模块就可以很方便的配置、连接到数据库&#xff0c;本次操作以MySQL为例&#xff0c;其中testjdbc数据库已经提前建好&#xff0c;里面有两张表emp_table 和 t_user&#xff0c;相关信息…

Linux线程编程

参考&#xff1a;Linux多线程编程初探 作者&#xff1a;峰子_仰望阳光 网址&#xff1a;https://www.cnblogs.com/xiehongfeng100/p/4620852.html 目录线程概述线程概念线程与进程区别为何用线程线程开发api概要线程创建、等待、退出线程创建线程退出线程等待线程ID获取及比较线…

Controlling Execution

2019独角兽企业重金招聘Python工程师标准>>> 逗号操作符 逗号操作符在java中特殊之处在于两个地方&#xff1a; 1. 定义同种类型的变量时可以这样写&#xff1a; int i10,j20;//只有同种变量才行 2. 在for循环中的初始化条件和变化的步骤中对于同种类型的可以连接…

前端 js 非控件 使用标签打印机 打印二维码和文本_青岛Web前端(HTML5)面试题分享...

HTML5是前端开发人员必须掌握的技能之一&#xff0c;那么在面试时&#xff0c;面试官常问到的HTML5的问题有哪些呢&#xff1f;青岛HTML51、Doctype作用&#xff1f;严格模式与混杂模式如何区分&#xff1f;它们有何意义&#xff1f;答&#xff1a;告知浏览器的解析器&#xff…

SpringBoot整合SpringBatch实用简例

SpringBatch主要是一个轻量级的大数据量的并行处理(批处理)的框架。 作用和Hadoop很相似&#xff0c;不过Hadoop是基于重量级的分布式环境(处理巨量数据)&#xff0c;而SpringBatch是基于轻量的应用框架(处理中小数据)。 这里使用SpringBatch做了一个能跑的最简单例子&#xff…

安卓APP_ Fragment(1)—— Fragment概念、基础用法、动态变换、管理栈

摘自&#xff1a;安卓APP_ Fragment&#xff08;1&#xff09;—— Fragment概念、基础用法、动态变换、管理栈 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-15 23:32:31 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115716359 目录…

谷歌五笔输入法电脑版_“五笔输入法”打字速度更快,为什么却没啥人用?

现如今&#xff0c;随着国内经济水平的不断发展&#xff0c;电脑和手机都已经不再是稀罕玩意&#xff0c;因为现在国内有很多的厂家都在生产手机和电脑&#xff0c;导致这些电子产品的价格下降&#xff0c;所以我们很轻易就能够买得起这样的产品。而在手机、电脑普及之后&#…

安卓APP_ Fragment(2)—— Activity与Fragment的通信

摘自&#xff1a;安卓APP_ Fragment&#xff08;2&#xff09;—— Activity与Fragment的通信 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-16 17:23:44 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115743009 目录 Activity与Fragm…

java socket 判断Socket连接失效

要判断socket连接链路是否可用时&#xff0c;不能通过socket.isClosed() 和 socket.isConnected() 方法判断&#xff0c;要通过心跳包 socket.sendUrgentData(0xFF) 。 当第一次连接成功后&#xff0c; socket.isClosed() false, socket.isConnected()true&#xff0c;只有在自…

安卓APP_ Fragment(3)—— Fragment的生命周期

摘自&#xff1a;安卓APP_ Fragment&#xff08;3&#xff09;—— Fragment的生命周期 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-16 22:32:12 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115768202 目录 Fragment生命周期函数一…

安卓APP_ 布局(8) —— 基于 RecyclerView 的 ViewPager2翻页

摘自&#xff1a;安卓APP_ 布局&#xff08;8) —— 基于 RecyclerView 的 ViewPager2翻页 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-20 15:37:54 网址&#xff1a;https://blog.csdn.net/weixin_44742824/article/details/115803077 viewpager2 是对Recycler…

安卓APP_ Fragment(4)—— Fragment + ViewPager2 模拟微信首页 (1)两者联动实现翻页

摘自&#xff1a;安卓APP_ Fragment&#xff08;4&#xff09;—— Fragment ViewPager2 模拟微信首页 &#xff08;1&#xff09;两者联动实现翻页 作者&#xff1a;丶PURSUING 发布时间&#xff1a; 2021-04-20 17:46:59 网址&#xff1a;https://blog.csdn.net/weixin_4474…

Linux网络编程(Socket)

目录网络编程&#xff08;Socket&#xff09;概述引入网络编程通识扫盲socket套接字套接字描述符字节序socket编程步骤Linux提供的API简析创建套接字即连接协议[socket]&#xff08;服、客&#xff09;绑定IP和端口[bind]&#xff08;服&#xff09;地址转换api字节序转换api监…

嵌入式开发概述(树莓派介绍)

目录嵌入式定义嵌入式芯片选型ARM架构ARM树莓派嵌入式定义 国内普遍认同的嵌入式系统的定义是以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软硬件可裁剪&#xff0c;适应应用系统对功耗、可靠性、成本、体积、功耗等严格要求的专用计算机系统。 嵌入式系统是软件和…

ubuntu 16gcc g++版本降级

打算在ubuntu16上编译linux3.4.66内核&#xff0c;但是遇到 In file included from include/linux/compiler.h:48:0, from include/linux/stddef.h:4, from include/linux/posix_types.h:4, from include/linux/types.h:17, from include/linux/page-flags.h:8, from kern…