提升ListView運行效率兩個方法,listview效率

來源:互聯網
上載者:User

提升ListView運行效率兩個方法,listview效率
一、首先我們先實現ListView的構建工作

1.定義一個實體類,作為ListView適配器的適配類型。建立Fruit類,代碼如下:

package org.lxh.demo;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;}}


2.然後需要為ListView的子項指定一個我們自訂的布局,在layout目錄下建立fruit_item.xml,代碼如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <ImageView        android:id="@+id/fruit_image"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/fruit_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:layout_marginLeft="10sp" /></LinearLayout>


3.接下來我們要建立一個適配器,這個適配器繼承自ArrayAdapter,並指定泛型型別為Fruit類。建立FruitAdapter,代碼如下:

package org.lxh.demo;import java.util.List;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;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=LayoutInflater.from(getContext()).inflate(resourceId, null);ImageView fruitImageView=(ImageView)view.findViewById(R.id.fruit_image);TextView fruitTextView=(TextView)view.findViewById(R.id.fruit_name);fruitImageView.setImageResource(fruit.getImageId());fruitTextView.setText(fruit.getName());return view;}}


4.下面在main.xml中加入一個ListView:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <ListView        android:id="@+id/list_view"        android:layout_width="fill_parent"        android:layout_height="wrap_content" /></LinearLayout>


5.然後MainActivity:

package org.lxh.demo;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;public class Hello extends Activity {private List<Fruit> fruitList = new ArrayList<Fruit>();public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); // 生命週期方法super.setContentView(R.layout.main); // 設定要使用的布局管理器initFruits();FruitAdapter adapter = new FruitAdapter(Hello.this,R.layout.fruit_item, fruitList);ListView listView = (ListView) findViewById(R.id.list_view);listView.setAdapter(adapter);}private void initFruits() {Fruit appleFruit = new Fruit("Apple", R.drawable.apple_pic);fruitList.add(appleFruit);Fruit bananaFruit = new Fruit("Banana", R.drawable.banana_pic);fruitList.add(bananaFruit);Fruit orangeFruit = new Fruit("Orange", R.drawable.orange_pic);fruitList.add(orangeFruit);Fruit waterFruit = new Fruit("Apple", R.drawable.watermelon_pic);fruitList.add(waterFruit);}}


運行執行個體如下:

二、提升ListView的運行效率

ListView這個控制項很難用,因為它有很多細節可以最佳化,其中運行效率就是很重要的一點。目前我們的ListView的運行效率很低,因為在FruitAdapter的getView()方法中每次都將布局重新載入了一遍,當ListView快速滾動的時候就會成為效能的瓶頸。

 仔細觀察,getView()方法還有一個convertView參數,這個參數用於將之前載入好的布局進行緩衝,以便之後可以進行重用。修改FruitAdapter中的代碼:

package org.lxh.demo;import java.util.List;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;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;if (convertView == null) {view = LayoutInflater.from(getContext()).inflate(resourceId, null);} else {view = convertView;}ImageView fruitImageView = (ImageView) view.findViewById(R.id.fruit_image);TextView fruitTextView = (TextView) view.findViewById(R.id.fruit_name);fruitImageView.setImageResource(fruit.getImageId());fruitTextView.setText(fruit.getName());return view;}}


可以看到,現在我們在getView()方法中進行了判斷,如果convertView為空白,則使用LayoutInflater去載入布局,如果不為空白則直接對convertView進行重用。這樣就大大提高了ListView 的運行效率,在快速滾動的時候也可以變現出更好的效能。

不過目前我們的代碼還是可以最佳化的,雖然我們現在已經不會再重複去載入布局,但是每次在getView()方法中還是會調用View的findViewById()方法去擷取一次控制項的執行個體。我們藉助一個ViewHolder來對這部分效能進行最佳化,修改FruitAdapter中的代碼:

package org.lxh.demo;import java.util.List;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;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();}viewHolder.fruitImage.setImageResource(fruit.getImageId());viewHolder.fruitName.setText(fruit.getName());return view;}class ViewHolder {ImageView fruitImage;TextView fruitName;}}


我們新增了一個內部類ViewHolder,用於對控制項的執行個體進行緩衝。當converView為空白的時候建立一個ViewHoler對象,並將控制項的執行個體都放在ViewHolder裡,然後調用View的setTag()方法,將ViewHolderObject Storage Service在View中。噹噹converView不為空白則調用View的getTag()方法,把ViewHolder重新取出。這樣所有的控制項的執行個體都緩衝在了ViewHolder裡,就沒有必要每次都通過findViewById()方法來擷取控制項的執行個體了。通過這兩步最佳化之後,ListView的運行效率就已經非常不錯了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.