Android(java)学习笔记88:BaseAdapter适配器重写之getView()
1. BaseAdapter适配器重写 之getView():
(1)View getview(int position, View convertview, ViewGroup parent )
第一个参数position----------该视图在适配器数据中的位置
第二个参数convertView-----旧视图
第三个参数parent------------此视图最终会被附加到的父级视图
特别注意:convertview参数
首先讲下ListView的原理:ListView中的每一个Item显示都需要Adapter调用一次getView的方法,这个方法会传入一个convertView的参数,返回的View就是这个Item显示的View。
如果当Item的数量足够大,再为每一个Item都创建一个View对象,必将占用很多内存,创建View对象(mInflater.inflate(R.layout.lv_item, null);从xml中生成View,这是属于IO操作)也是耗时操作,所以必将影响性能。
Android提供了一个叫做Recycler(反复循环器)的构件,就是当ListView的Item从上方滚出屏幕视角之外,对应Item的View会被缓存到Recycler中,相应的会从下方生成一个Item,而此时调用的getView中的convertView参数就是滚出屏幕的Item的View,所以说convertView 我们可以复用它,这样就省去了new View的大量开销。
(2)ViewHolder(自定义的):
getView方法:
public View getView(int position, View convertView, ViewGroup parent) {
System.out.println("getView " + position + " " + convertView);
ViewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.lv_item, null);
holder = new ViewHolder();
holder.textView = (TextView)convertView.findViewById(R.id.tv_text);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}
ViewHolder:
package com.shinylife.smalltools; import android.widget.ImageView;
import android.widget.TextView; public class ViewHolder {
public ImageView imgView;
public TextView textView;
}
为什么要ViewHolder(自定义的)这样一个东西, 因为无论convertView是不是null, 都需要对ViewHolder中的TextView和ImageView进行赋值操作, 貌似没有什么必要.
其实不是这么简单, 这样做是一种拿空间换时间的方式. 增加一个对象ViewHolder , 却省去了一系列的findViewById()的时间,大家都知道, 在一个View的树形结构上使用findViewById()查找控件是需要时间的, 而且这个树形结构越复杂, 花费的时间越多。
注意:
我们都知道在getView方法中的操作是这样的:先从xml中创建view对象(inflate操作,我们采用了重用convertView方法优化),然后在这个view去findViewById,找到每一个子View,如:一个TextView等。
这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,就是使用viewHolder,把每一个子View都放在Holder中,当第一次创建convertView对象时,把这些子view找出来。
然后用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。当第二次重用convertView时,只需从convertView中getTag取出来就可以。
(3)setTag()/getTag():View中的setTag(Onbect)表示给View添加一个格外的数据,以后可以用getTag()将这个数据取出来。
可以用在多个Button添加一个监听器,每个Button都设置不同的setTag。这个监听器就通过getTag来分辨是哪个Button 被按下:
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button1 = (Button) findViewById(R.id.Button01);
Button button2 = (Button) findViewById(R.id.Button02);
Button button3 = (Button) findViewById(R.id.Button03);
Button button4 = (Button) findViewById(R.id.Button04);
MyListener listener = new MyListener();
button1.setTag(1);
button1.setOnClickListener(listener);
button2.setTag(2);
button2.setOnClickListener(listener);
button3.setTag(3);
button3.setOnClickListener(listener);
button4.setTag(4);
button4.setOnClickListener(listener);
}
public class MyListener implements View.OnClickListener {
@Override
public void onClick(View v) {
int tag = (Integer) v.getTag();
switch (tag) {
case 1:
System.out.println("button1 click");
break;
case 2:
System.out.println("button2 click");
break;
case 3:
System.out.println("button3 click");
break;
case 4:
System.out.println("button4 click");
break;
}
}
}
}
在写ListView 时候要重写BaseAdapter:
需要在没个item都加上button 点击button做相应操作
这个时候需要button里面设置下 这行的属性
button.setTag(item.user.name);
然后处理button事件。
这个东西在一些需要用到Adapter自定控件显示方式的时候非常有用
Adapter 有个getView方法,可以使用setTag把查找的view缓存起来方便多次重用:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mWidgetsSwitchApp.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.app_gallery_item, null);
vh = new ViewHolder();
vh.view1 = (ImageView) convertView.findViewById(R.id.view1);
vh.view2 = (ImageView) convertView.findViewById(R.id.view2);
vh.view3 = (ImageView) convertView.findViewById(R.id.view3);
vh.view4 = (ImageView) convertView.findViewById(R.id.view4);
convertView.setTag(vh);
} else {
vh = (ViewHolder) convertView.getTag();
}
//其他的代码可以直接使用 vh.view1、vh.view2、vh.view3 、vh.view4
}
你可以看看android的源码,特别有listview的,你就会发现这个函数很多时候有妙用!呵呵!
我的一点理解是,绑定数据,特别是绑定数据到view。而且可以用getTag()取得,很方便,而且是任意类型的数据,真的很酷。
在实例BaseAdapter()的getView(position, convertView, par)里有用到。convertView这里会用到setTag() getTag()。就可以生成convertView并复用里面的widget,一直觉得这个东西没啥用setTag(),不过只要能用上 就是比较巧的了
在一个程序中呢 我有好多个button 我想点击一个出现1, 点击第二个出现2
for (int i = 0; i < 20; i++) {
cells[i] = (ImageView) findViewById(cellIDs[i]);
cells[cellnumber++].setOnClickListener(new OnClickListener() {
public void onClick(View v){
cellClicked(cellnumber, v);
}});
}
上面的代码效率不高 而且 无论点击哪一个都会出现21 当然这是我逻辑错误
那怎么实现呢
OnClickListener listener = new OnClickListener() {
public void onClick(View v) {
int cellId = (Integer) v.getTag();
cellClicked(cellId, v);
}
}
View v;
for (int i = 0; i < 20; i++) {
v = findViewById(cellIDs[i]);
v.setOnClickListener(listener);
v.setTag(i);
}
这样呢就实例话一个listener,同时通过tag传值就不是每一个实例都做了
Android(java)学习笔记88:BaseAdapter适配器重写之getView()的更多相关文章
- Java学习笔记(9)--- 重写,重载,多态
1.重写: a.定义: 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变.即外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为. 也就是说子类能 ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
- Android:日常学习笔记(8)———探究UI开发(5)
Android:日常学习笔记(8)———探究UI开发(5) ListView控件的使用 ListView概述 A view that shows items in a vertically scrol ...
- java学习笔记之基础篇
java选择语句之switch //switch可以用于等值判断 switch (e) //int ,或则可以自动转化成int 的类型,(byte char short)枚举jdk 7中可以防止字 ...
- 0035 Java学习笔记-注解
什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...
- 0032 Java学习笔记-类加载机制-初步
JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
随机推荐
- Ocelot(二)- 请求聚合与负载均衡
Ocelot(二)- 请求聚合与负载均衡 作者:markjiang7m2 原文地址:https://www.cnblogs.com/markjiang7m2/p/10865511.html 源码地址: ...
- 洛谷P3694 邦邦的大合唱站队/签到题
P3694 邦邦的大合唱站队/签到题 题目背景 BanG Dream!里的所有偶像乐队要一起大合唱,不过在排队上出了一些问题. 题目描述 N个偶像排成一列,他们来自M个不同的乐队.每个团队至少有一个偶 ...
- 解读人:范徉,Methylome and Metabolome Analyses Reveal Adaptive Mechanisms in Geobacter sulfurreducens Grown on Different Terminal Electron Acceptors(甲基化组学和代谢组学分析发现Geobacter sulfurreducens生长在不同电子终受体中的适应机制)
发表时间: (2019年4月) IF:3.950 单位: Fujian Provincial Key Laboratory of Soil Environmental Health and Regul ...
- 解决Nginx启动失败
一.Nginx下载http://nginx.org/en/download.html 二.Nginx启动失败原因1.本人下载的是nginx-1.12.1(稳定版),下载完解压后,进入路径中,start ...
- JS事件冒泡机制和兼容性添加事件
本篇文章主要来讲讲 事件的冒泡机制 和 添加事件的几种方法. 一. JS的时间传递顺序: 捕获阶段 -> 目标阶段 -> 冒泡阶段 捕获阶段是指从父层往子层找.比如 <body> ...
- SerializeUtil
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInpu ...
- Jmeter4.0---- HTTP请求默认值(15)
1.说明 在线程组中,添加”HTTP请求默认值”,并填写 协议,服务器名称/IP ,端口号,编码等 ,之后该线程组中的所有请求,可以不用填写这几项,启动后会直接调用”HTTP请求默认值”中的数据,方便 ...
- 打印BroadcastReceiver的所有接受者
Android中收到短信等事件都是通过广播发送给应用程序的,手机卫士等程序都是通过注册高优先级的BroadcastReceiver来实现短信防火墙等功能.对于我们来说很想知道系统中都有哪些程序注册了B ...
- Java文件与io——NewIO
为啥要使用NIO? NIO的创建目的是为了让JAVA程序员可以实现高速I/O而无需编写自定义的本机代码.NIO将最耗时的I/O操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度 流与快的 ...
- jstl core and jstl fn
jstl标签使用时必须加taglib:<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core&quo ...