ListView的使用用ViewHolder提升效率


public class

ListView

extends AbsListView
java.lang.Object
   ↳android.view.View
    ↳android.view.ViewGroup
     ↳android.widget.AdapterView<T extends android.widget.Adapter>
      ↳android.widget.AbsListView
       ↳android.widget.ListView

Class Overview

A view that shows items in a vertically scrolling list. The items come from theListAdapter associated with this view.

 

public class

ArrayAdapter

extends BaseAdapter
implements Filterable

java.lang.Object
   ↳android.widget.BaseAdapter
    ↳android.widget.ArrayAdapter<T>
Class Overview

A concrete BaseAdapter that is backed by an array of arbitrary objects. By default this class expects that the provided resource id references a single TextView. If you want to use a more complex layout, use the constructors that also takes a field id. That field id should reference a TextView in the larger layout resource.

However the TextView is referenced, it will be filled with the toString() of each object in the array. You can add lists or arrays of custom objects. Override the toString() method of your objects to determine what text will be displayed for the item in the list.

To use something other than TextViews for the array display, for instance, ImageViews, or to have some of data besides toString() results fill the views, overridegetView(int, View, ViewGroup) to return the type of view you want.

 

1、ListView的简单使用

Demo:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="sunny.example.listviewsimple.MainActivity" ><ListViewandroid:id="@+id/list_view"android:layout_width="match_parent"android:layout_height="match_parent"/></RelativeLayout>

 

MainActivity.java

package sunny.example.listviewsimple;import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;public class MainActivity extends ActionBarActivity {private String[] data = {"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","Cherry","Mango"};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data);ListView listView = (ListView)findViewById(R.id.list_view);listView.setAdapter(adapter);}
}


2、提升ListView的运行效率ViewHolder、自定义ListView的界面(例:包括一个ImageView和一个TextView)

 

上例一个item只能显示一段文本,现在自定义一个ListView的界面。自定义一个Fruit类,作为ListView适配器的适配类型。

Fruit.java

package com.example.listviewtest;public class Fruit {private String name;private int imageId;public Fruit(String name,int imageId){this.name = name;this.imageId = imageId;}public String getName(){return name;}public int getImageId(){return imageId;}}

Fruit类有两个字段,name表示水果的名字,iamgeId表示水果对应的图片资源id。

然后为ListView的item自定义一个布局

fruit_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"><ImageViewandroid:id="@+id/fruit_image"android:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:id="@+id/fruit_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginLeft="10dip"/>
</LinearLayout>
子item布局中定义一个ImageView用于显示水果图片,TextView用于显示水果名字。
创建一个自定义适配器FruitAdapter继承自ArrayAdapter,将泛型指定为Fruit类。
 
FruitAdapter中用到的类与方法:
public abstract class

LayoutInflater

extends Object
java.lang.Object
   ↳android.view.LayoutInflater

Class Overview

Instantiates a layout XML file into its corresponding View objects. It is never used directly. Instead, usegetLayoutInflater() orgetSystemService(String) to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on. For example:

LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

public static LayoutInflater from (Context context)

Added in API level 1

Obtains the LayoutInflater from the given context.

public View inflate (int resource,ViewGroup root)

Added in API level 1

Inflate a new view hierarchy from the specified xml resource. Throws InflateException if there is an error.

Parameters
resourceID for an XML layout resource to load (e.g., R.layout.main_page)
rootOptional view to be the parent of the generated hierarchy.
Returns
  • The root View of the inflated hierarchy. If root was supplied, this is the root View; otherwise it is the root of the inflated XML file.
 
FruitAdapter.java
public class FruitAdapter extends ArrayAdapter<Fruit> {private int resourceId;public  FruitAdapter(Context context,int textViewResourceId,List<Fruit> objects){super(context,textViewResourceId,objects);resourceId = textViewResourceId;}@Overridepublic View getView(int position,View convertView,ViewGroup parent){//得到当前项的Fruit实例Fruit fruit = getItem(position);//LayoutInflater来为这个子项加载布局View view = LayoutInflater.from(getContext()).inflate(resourceId,null);ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);TextView textView = (TextView) view.findViewById(R.id.fruit_name);fruitImage.setImageResource(fruit.getImageId());fruitName.setText(fruit.getName());return view;}
}

重写了ArrayAdapter的 getView()方法,这个方法在每个子item被滚动到屏幕内的时候会被调用。

目前ListView的运行效率是很低的,因为每个子item被滚动到屏幕内的时候会调用getView()在getView()方法中每次都将布局加载了一遍。

优化方法一:

public View getView(int position,View convertView,ViewGroup parent)

方法中有一个convertView参数,用于将之前加载好的布局进行缓存,以便以后重用。

修改上述代码:

 

public class FruitAdapter extends ArrayAdapter<Fruit> {private int resourceId;public  FruitAdapter(Context context,int textViewResourceId,List<Fruit> objects){super(context,textViewResourceId,objects);resourceId = textViewResourceId;}@Overridepublic View getView(int position,View convertView,ViewGroup parent){//得到当前项的Fruit实例Fruit fruit = getItem(position);View view;//convertView为空,使用LayoutInflater加载布局//不为空,则直接对convertView进行重用if(convertView==null){view = LayoutInflater.from(getContext()).inflate(resourceId, null);}else{view = convertView;}ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);TextView textView = (TextView) view.findViewById(R.id.fruit_name);fruitImage.setImageResource(fruit.getImageId());fruitName.setText(fruit.getName());return view;}
}

 

目前代码还可以优化,虽然现在已经不会再重复去加载布局,但每次getView()方法中还是会调用View的findViewById()来获取一次控件实例。下面使用ViewHolder继续优化:

优化方法二:新增一个内部类ViewHolder:
 
class ViewHolder{ImageView fruitImage;TextView fruitName;}

用于对对象的实例进行缓存。当convertView为空,创建一个ViewHolder对象,并将控件的实例都存放在ViewHolder里,然后调用View的setTag()方法将ViewHolder 对象存储在view中。当convertView不为空时,调用View的getTag()方法把ViewHolder取出。这样所有的控件实例都缓存在ViewHolder里了,就不用每次都通过findViewById()方法获取控件实例了。
 
FruitAdapter.java
package com.example.listviewtest;import java.util.List;import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;@SuppressLint("ViewHolder")
public class FruitAdapter extends ArrayAdapter<Fruit> {private int resourceId;public  FruitAdapter(Context context,int textViewResourceId,List<Fruit> objects){super(context,textViewResourceId,objects);resourceId = textViewResourceId;}@Overridepublic View getView(int position,View convertView,ViewGroup parent){Fruit fruit = getItem(position);View view;ViewHolder viewHolder;if(convertView==null){view = LayoutInflater.from(getContext()).inflate(resourceId, null);viewHolder = new ViewHolder();viewHolder.fruitImage = (ImageView)view.findViewById(R.id.fruit_image);viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);view.setTag(viewHolder);}else{view = convertView;viewHolder = (ViewHolder)view.getTag();}//View view = LayoutInflater.from(getContext()).inflate(resourceId,null);//ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);//TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);//fruitImage.setImageResource(fruit.getImageId());//fruitName.setText(fruit.getName());viewHolder.fruitImage.setImageResource(fruit.getImageId());viewHolder.fruitName.setText(fruit.getName());return view;}class ViewHolder{ImageView fruitImage;TextView fruitName;}}

activity_main.xml
 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><ListViewandroid:id="@+id/list_view"android:layout_width="match_parent"android:layout_height="match_parent"></ListView></LinearLayout>
 
MainActivity.java
package com.example.listviewtest;import java.util.ArrayList;
import java.util.List;import android.app.Activity;
import android.content.Context;
//import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Toast;import android.widget.ListView;public class MainActivity extends Activity {private String[] data = {"Apple","Banana","Orange","Watermelon","Pear","Grape","Pineapple","Strawberry","cherry","Mango"};private List<Fruit> fruitList = new ArrayList<Fruit>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initFruits();
//public FruitAdapter(Context context,int textViewResourceId,List<Fruit> objects)	FruitAdapter adapter = new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);//ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,data);ListView listView = (ListView) findViewById(R.id.list_view);listView.setAdapter(adapter);listView.setOnItemClickListener(new OnItemClickListener(){@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {// TODO Auto-generated method stubFruit fruit = fruitList.get(position);Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();}});}private void initFruits() {// TODO Auto-generated method stubFruit apple = new Fruit("Apple",R.drawable.ic_launcher);fruitList.add(apple);Fruit banana = new Fruit("Banana",R.drawable.ic_launcher1);fruitList.add(banana);Fruit orange = new Fruit("Orange",R.drawable.ic_launcher2);fruitList.add(orange);Fruit Watermelon = new Fruit("Watermelon",R.drawable.ic_launcher3);fruitList.add(Watermelon);Fruit Pear = new Fruit("Pear",R.drawable.ic_launcher4);fruitList.add(Pear);Fruit Grape = new Fruit("Grape",R.drawable.ic_launcher5);fruitList.add(Grape);Fruit Pineapple = new Fruit("Pineapple",R.drawable.ic_launcher6);fruitList.add(Pineapple);Fruit Strawberry = new Fruit("S trawberry",R.drawable.ic_launcher7);fruitList.add(Strawberry);Fruit cherry = new Fruit("Cherry",R.drawable.ic_launcher8);fruitList.add(cherry);Fruit mango = new Fruit("Mango",R.drawable.ic_launcher9);fruitList.add(mango);}
}


 

 

 


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

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

相关文章

电脑还原Mac地址

之前修改过电脑Mac&#xff0c;现在与手机Mac冲突&#xff0c;导致手机无法连接校园网。 控制面板——》打开网络和共享中心——》选择更改适配器设置 本地连接——》右键选择属性 上图选择配置 高级——》在下拉菜单中选择网络地址——》右边选为“不存在” 之后本地连接会自…

聊天ListView使用ViewHolder

聊天界面会展示至少两种布局&#xff0c;即收到消息和发送消息。这样一个ListView与平时使用的ListView的最大不同&#xff0c;在于它有两个不同的布局&#xff1a;收到的布局和发送的布局。需要利用Adapter实现这样的效果。即需要在获取布局的时候判断该获取哪个布局。 public…

动态改变ListView布局

在getView()时&#xff0c;通过判断选择加载不同的布局。 点击某个item的时候&#xff0c;变为foucus状态&#xff0c;其他的items还原。 下面用两个方法给item设置两个不同的布局。 //foucus状态&#xff0c;显示一个ImageViewprivate View addFocusView(int i) {ImageView…

jpa 关系拥有方_JPA:确定关系的归属方

jpa 关系拥有方使用Java Persistence API&#xff08;JPA&#xff09;时&#xff0c;通常需要在两个实体之间创建关系。 这些关系是通过使用外键在数据模型&#xff08;例如数据库&#xff09;中定义的&#xff0c;而在我们的对象模型&#xff08;例如Java&#xff09;中则使用…

获取View坐标

滑动一个View&#xff0c;即移动一个View&#xff0c;改变其当前所处的位置&#xff0c;通过不断改变View的坐标实现滑动的效果。 1、Android坐标系&#xff1a;坐标原点在屏幕左上角。 public void getLocationOnScreen(int[] location) Computes the coordinates of this vi…

李宏毅 课程打包_按功能而不是按层打包课程

李宏毅 课程打包大多数企业Java应用程序在设计上都有一些相似之处。 这些应用程序的打包通常由它们使用的框架&#xff08;如Spring&#xff0c;EJB或Hibernate等&#xff09;驱动。或者&#xff0c;您可以按功能对打包进行分组。 像任何其他有关建模的项目一样&#xff0c;这也…

Java反射,但速度更快

在编译时不知道Java类的最快方法是什么&#xff1f; Java框架通常会这样做。 很多。 它可以直接影响其性能。 因此&#xff0c;让我们对不同的方法进行基准测试&#xff0c;例如反射&#xff0c;方法句柄和代码生成。 用例 假设我们有一个简单的Person类&#xff0c;其中包含名…

Git时间

1、Git是目前世界上最先进的分布式版本控制系统。和集中式版本控制系统相比&#xff0c;分布式版本控制系统的安全性要高很多&#xff0c;因为每个人电脑里都有完整的版本库&#xff0c;某一个人的电脑坏掉了不要紧&#xff0c;随便从其他人那里复制一个就可以了。而集中式版本…

java中update_Java 7 Update 21安全改进的详细信息

java中updateOracle昨天发布了三个Java更新 。 重要的是要注意它们包含一些与安全性相关的更改。 一段时间以来&#xff0c;这些变更中的大多数已经宣布&#xff0c;首先要注意的是Oracle按计划交付。 Oracle公司Java平台安全经理米尔顿史密斯&#xff08;Milton Smith&…

访问GitHub超慢的解决办法

是github某个CDN(Content Delivery Network&#xff0c;即内容分发网络?)被屏蔽所致。 附件--->记事本&#xff08;选择以管理员身份运行&#xff09;——文件——打开C:\Windows\System32\drivers\etc 右下角选择“所有文件” 选择hosts 打开 如图在这行下面添加绑定IP…

学习使用Whally GraalVM!

介绍 在Truffle在神圣的Graal中服务&#xff1a;Graal和Truffle在JVM上进行多语种语言解释的帖子中&#xff0c;我们得到了简短的介绍&#xff0c;并对Graal&#xff0c;Truffle及其周围的一些概念进行了深入研究。 但是&#xff0c;如果不深入研究实用性&#xff0c;那么任何技…

Android样式开发---shape

Thanks to:转载自Keegan小钢 原文链接&#xff1a;http://keeganlee.me/post/android/20150830 一个应用&#xff0c;应该保持一套统一的样式&#xff0c;包括Button、EditText、ProgressBar、Toast、Checkbox等各种控件的样式&#xff0c;还包括控件间隔、文字大小和颜色、阴影…

SwipeRefreshLayout官方推荐下拉刷新

SwipeRefreshLayoutpublic class SwipeRefreshLayout extends ViewGroup implements NestedScrollingParent, NestedScrollingChildjava.lang.Object↳android.view.View↳android.view.ViewGroup↳ android.support.v4.widget.SwipeRefreshLayout API doc&#xff1a;http://…

开源PagerSlidingTabStrip的使用Tab与ViewPager的完美结合

链接地址&#xff1a;https://github.com/astuetz/PagerSlidingTabStrip 下载PagerSlidingTabStrip-master 将com.astuetz包&#xff0c;res下的下的资源复制进工程 布局文件&#xff1a;activity_main.xml <RelativeLayout xmlns:android"http://schemas.android.co…

android动画详解

转自&#xff1a;工匠若水 http://blog.csdn.net/yanbober 1 背景 不能只分析源码呀&#xff0c;分析的同时也要整理归纳基础知识&#xff0c;刚好有人微博私信让全面说说Android的动画&#xff0c;所以今天来一发Android应用的各种Animation大集合。英文厉害的请直接移步参考…

凹数科技笔试

一、Java 1、成员变量作用域public/protected/defaultprivate/区别&#xff1f; public&#xff1a;该成员变量或其方法对当前类、同一包、子类、其他包都可见&#xff0c;所有类和对象都可以直接访问。 protected&#xff1a;该成员变量或其方法对当前类、同一包、子类都可…

上传至GitHub

在工作目录下&#xff1a; git init git status git add . git commit -m"IndoorLocation" git status git remote add origin githttps://github.com/HiSunny/HelloInLoc.git git pull https://github.com/HiSunny/HelloInLoc.git master git push https://…

Activity的LaunchMode和taskAffinity

Thanks to:http://www.cnblogs.com/SteveMing/archive/2012/04/24/2459575.html 【原】Activity的LaunchMode和taskAffinity 做项目到现在都一直没有理解LaunchMode有什么用&#xff0c;或许根本就没真正花心思去看&#xff0c;所以今天把这部分整理下。 设置Activity的Launc…

gradle spring_使用Gradle的简单Spring MVC Web应用程序

gradle spring除了我们现在将使用Spring MVC而不是原始servlet之外&#xff0c;该文章将与我们之前的文章Simple Gradle Web Application相似。 使用Gradle运行基本的Spring MVC应用程序确实很容易。 您可以在Github上下载本教程的源代码。 先决条件 安装Gradle 我们的基本项…

绘制Nine-Patch图片

Android sdk----->tools----->draw9patch.bat 打开draw9patch.bat文件 File--》open 0-patch将要绘制的.png图片加载进来 ctrl 图片边缘点击鼠标左键 绘制出线条&#xff0c;表示图片需要被拉伸的部分 File--save 9-patch 文件名pp.9.png。