ListView在android開放中用的比較多,所以接下來就進行ListView的使用的講解。
首先創建一個android項目,項目名爲ListViewTest.
ListView的簡單使用
修改佈局文件,修改後代碼如下:
- <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"
- >
- <ListView
- android:id="@+id/list_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- ></ListView>
- </LinearLayout>
修改MainActivity的代碼:
- package com.wj.listviewtest;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
- public class MainActivity extends Activity {
- private String [] data={"apple","banana","orange",
- "watermelon","pear","grape","pineapple","strawberry",
- "cherry","mango"};
- @Override
- protected 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);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- }
運行程序結果如下:
ListView是用於顯示大量數據的,這些數據我們可以事先準備好,也可以從網上或者數據中中讀取。
android.R.layout.simple_list_item_1是作爲ListView子項佈局的id,這是android內置的佈局文件裏面只有一個TextView,可用於簡單地顯示一段文本。
2.定製ListView的界面
首先準備一組圖片,分別對應上面提供的水果。
接着定義一個實體類,作爲ListView適配器的適配類型,新建Fruit類,代碼如下:
- package com.wj.listviewtest;
- public class Fruit {
- private String name;//水果名
- private int imageId;//水果圖片的資源id
- //無參構造函數
- public Fruit(){}
- //有參構造函數
- public Fruit(String name,int imageId){
- this.name=name;
- this.imageId=imageId;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getImageId() {
- return imageId;
- }
- public void setImageId(int imageId) {
- this.imageId = imageId;
- }
- }
Fruit類中只有2個字段,name表示水果的名字,imageId表示水果對應圖片的資源id,然後需要爲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="match_parent"
- android:layout_height="match_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="10dip"
- />
- </LinearLayout>
這個佈局中我們定義了一個ImageView用於顯示水果的圖片,又定義了一個TextView用於顯示水果的名稱。
接着我們要創建一個自定義的適配器,這個適配器繼承自ArrayAdapter,並將泛型指定爲Fruit。新建一個類FruitAdapter代碼如下:
- package com.wj.listviewtest;
- 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);
- // TODO Auto-generated constructor stub
- /*
- * 重寫了父類的構造函數,用於將上下文,ListView子項佈局的id和數據都傳進來。
- * */
- resourceId=textViewResourceId;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- //return super.getView(position, convertView, parent);
- /*
- * 重寫getView方法,這個方法在每個子項被滾動到屏幕內的時候會被調用,在getView方法中
- * ,首先通過getItem方法得到當前項的Fruit實例,然後使用LayoutInflater來爲這個子項加載
- * 我們傳入的佈局,接着調用View的findViewById方法分別獲取到ImageView和TextView的實例,
- * 並分別調用他們的setImageResource和setText方法來設置顯示的圖片和文字,最後返回佈局
- * */
- Fruit fruit=getItem(position);//獲取當前項的Fruit實例
- //初始話ListView的子項佈局
- 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());
- return view;
- }
- }
修改MainActivity的代碼如下:
- package com.wj.listviewtest;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.widget.ArrayAdapter;
- 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>();
- @Override
- protected 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);*/
- initFruits();//初始化水果
- FruitAdapter adapter=new FruitAdapter(MainActivity.this,
- R.layout.fruit_item, fruitList);
- ListView listView=(ListView) findViewById(R.id.list_view);
- //設置適配器
- listView.setAdapter(adapter);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- public void initFruits(){
- Fruit apple=new Fruit("apple",R.drawable.apple_pic);
- fruitList.add(apple);
- Fruit banana=new Fruit("banana",R.drawable.banana_pic);
- fruitList.add(banana);
- Fruit orange=new Fruit("orange",R.drawable.orange_pic);
- fruitList.add(orange);
- Fruit watermelon=new Fruit("watermelon",R.drawable.watermelon_pic);
- fruitList.add(watermelon);
- Fruit pear=new Fruit("pear",R.drawable.pear_pic);
- fruitList.add(pear);
- Fruit grape=new Fruit("grape",R.drawable.grape_pic);
- fruitList.add(grape);
- Fruit pineapple=new Fruit("pineapple",R.drawable.pineapple_pic);
- fruitList.add(pineapple);
- Fruit strawberry=new Fruit("strawberry",R.drawable.strawberry_pic);
- fruitList.add(strawberry);
- Fruit cherry=new Fruit("cherry",R.drawable.cherry_pic);
- fruitList.add(cherry);
- Fruit mango=new Fruit("mango",R.drawable.mango_pic);
- fruitList.add(mango);
- }
- }
運行程序,結果如下:
這是一個簡單的界面,不過更加複雜的界面也可以通過修改fruit_item.xml文件來實現更加複雜的ListView。
下面我們來提示下ListView的運行效率。
目前我們的ListView的運行效率是很低的,因爲在FruitAdapter的getView方法中每次都要將佈局重寫加載了一遍,當ListView快速滾動的時候這就會成爲性能的瓶頸。仔細觀察,getView方法中還有一個convertView參數,這個參數用於將之前加載好的佈局進行緩存,以便之後可以進行重用,修改FruitAdapter中的代碼,帶入如下所示:
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- //return super.getView(position, convertView, parent);
- /*
- * 重寫getView方法,這個方法在每個子項被滾動到屏幕內的時候會被調用,在getView方法中
- * ,首先通過getItem方法得到當前項的Fruit實例,然後使用LayoutInflater來爲這個子項加載
- * 我們傳入的佈局,接着調用View的findViewById方法分別獲取到ImageView和TextView的實例,
- * 並分別調用他們的setImageResource和setText方法來設置顯示的圖片和文字,最後返回佈局
- * */
- Fruit fruit=getItem(position);//獲取當前項的Fruit實例
- View view;
- /*
- * 在getView()方法中進行判斷,如果convertView爲空,則使用LayoutInflater去加載佈局,
- * 如果不爲空,則直接對convertView進行重用。這樣可以大大提升ListView的效率,在快速滾動的時候
- * 也可以表現更好的性能。
- * */
- if(convertView==null){
- //初始話ListView的子項佈局
- view=LayoutInflater.from(getContext()).inflate(resourceId, null);
- }else{
- view=convertView;
- }
- /*//初始話ListView的子項佈局
- 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());
- return view;
- }
上面的代碼進行了部分的優化,雖然現在已經不用在重複的去加載佈局了,但是每次在getView方法中還是會調用View的view.findViewById()方法來獲取一次控件的實例。我們可以藉助一個ViewHolder來對這部分性能進行優化,修改FruitAdapter中的代碼,如下所示:
- package com.wj.listviewtest;
- 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);
- // TODO Auto-generated constructor stub
- /*
- * 重寫了父類的構造函數,用於將上下文,ListView子項佈局的id和數據都傳進來。
- * */
- resourceId=textViewResourceId;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- //return super.getView(position, convertView, parent);
- /*
- * 重寫getView方法,這個方法在每個子項被滾動到屏幕內的時候會被調用,在getView方法中
- * ,首先通過getItem方法得到當前項的Fruit實例,然後使用LayoutInflater來爲這個子項加載
- * 我們傳入的佈局,接着調用View的findViewById方法分別獲取到ImageView和TextView的實例,
- * 並分別調用他們的setImageResource和setText方法來設置顯示的圖片和文字,最後返回佈局
- * */
- Fruit fruit=getItem(position);//獲取當前項的Fruit實例
- View view;
- ViewHolder viewHolder;
- /*
- * 在getView()方法中進行判斷,如果convertView爲空,則使用LayoutInflater去加載佈局,
- * 如果不爲空,則直接對convertView進行重用。這樣可以大大提升ListView的效率,在快速滾動的時候
- * 也可以表現更好的性能。
- * */
- if(convertView==null){
- //初始話ListView的子項佈局
- 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);//將ViewHolder存儲在View中
- }else{
- view=convertView;
- viewHolder=(ViewHolder) view.getTag();//重新獲取ViewHolder
- }
- /*//初始話ListView的子項佈局
- 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);*/
- viewHolder.fruitImage.setImageResource(fruit.getImageId());
- viewHolder.fruitName.setText(fruit.getName());
- return view;
- }
- class ViewHolder{
- ImageView fruitImage;
- TextView fruitName;
- }
- }
通過上面兩步優化後,ListView的運行效率已經不錯了。
ListView的點擊事件
修改代碼如下:
- package com.wj.listviewtest;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.View;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
- import android.widget.Toast;
- 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>();
- @Override
- protected 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);*/
- initFruits();//初始化水果
- FruitAdapter adapter=new FruitAdapter(MainActivity.this,
- R.layout.fruit_item, fruitList);
- ListView listView=(ListView) findViewById(R.id.list_view);
- //設置適配器
- listView.setAdapter(adapter);
- /*
- * setOnItemClickListener()方法來爲ListView註冊一個監聽器,當用戶點擊了ListView
- * 中的任何一個子項時就會回調nItemClick()方法,在這個方法中可以通過position參數判斷出用戶點擊
- * 的是哪一個子項,然後獲取相應的水果,並通過Toast將水果的名字顯示出來。
- * */
- listView.setOnItemClickListener(new OnItemClickListener(){
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- // TODO Auto-generated method stub
- Fruit fruit=fruitList.get(position);
- Toast.makeText(MainActivity.this,
- fruit.getName(), Toast.LENGTH_SHORT).show();
- }
- });
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- public void initFruits(){
- Fruit apple=new Fruit("apple",R.drawable.apple_pic);
- fruitList.add(apple);
- Fruit banana=new Fruit("banana",R.drawable.banana_pic);
- fruitList.add(banana);
- Fruit orange=new Fruit("orange",R.drawable.orange_pic);
- fruitList.add(orange);
- Fruit watermelon=new Fruit("watermelon",R.drawable.watermelon_pic);
- fruitList.add(watermelon);
- Fruit pear=new Fruit("pear",R.drawable.pear_pic);
- fruitList.add(pear);
- Fruit grape=new Fruit("grape",R.drawable.grape_pic);
- fruitList.add(grape);
- Fruit pineapple=new Fruit("pineapple",R.drawable.pineapple_pic);
- fruitList.add(pineapple);
- Fruit strawberry=new Fruit("strawberry",R.drawable.strawberry_pic);
- fruitList.add(strawberry);
- Fruit cherry=new Fruit("cherry",R.drawable.cherry_pic);
- fruitList.add(cherry);
- Fruit mango=new Fruit("mango",R.drawable.mango_pic);
- fruitList.add(mango);
- }
- }
-
-
-
-
- 本文轉載自 http://blog.csdn.net/j903829182/article/details/40683293