Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> BaseAdapter的使用(筆記)

BaseAdapter的使用(筆記)

編輯:關於Android編程

\

 

 

適配器模式的應用:

 

1.降低程序耦合性

2.容易擴展

 

BaseAdapter

ListView的顯示與緩存機制:需要才顯示,顯示完就被會受到緩存。

BaseAdapter基本結構

--public int getCount(); 適配器中數據集中數據的個數

--public Object getItem(int position):獲取數據集中與指定索引對應的數據項

--public long getItem(int position):獲取指定行對應的ID

--public View getView(int position, ViewconverView, ViewGroup parent):獲取每一個Item的顯示內容

 

 

第一步: 創建布局文件 activity_main.xml 創建好了一個簡單的listView

創建item布局文件item.xml,其中有一個ImageView 兩個 TextView

 

activity_main.xml

 



    




 

 

item.xml

 


    
    
    
    



 

效果如圖:

\

 

第二步:創建一個Bean對象ItemBean,封裝item中顯示的內容,在主頁面MainActivity.java裡面創建數據源

ItemBean.java

 

public class ItemBean {

	public int ItemImageResid;
	public String Itemtitle;
	public String ItemContent;
	
	public ItemBean(int itemImageResid, String itemtitle, String itemContent) {
		super();
		ItemImageResid = itemImageResid;
		Itemtitle = itemtitle;
		ItemContent = itemContent;
	}
	
}

 

 

MainActivity.java

 

package com.example.sr;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List itemBeanList = new ArrayList();
        for(int i = 0; i < 20; i++){
        	itemBeanList.add(new ItemBean(R.drawable.ic_launcher, "我是標題"+i, "我是內容"+i));
        }
    }
}

 

 

第三步:新建MyAdapter類,繼承自BaseAdapter , 重寫裡面的方法,實現適配器

MyAdapter.java

 

package com.example.sr;

import java.util.List;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class MyAdapter extends BaseAdapter {

	private List mList;
	
	public MyAdapter(List list){  //數據源與適配器進行了關聯
		mList = list;
	}
	
	@Override
	public int getCount() { //返回ListView需要顯示的數據量
		// TODO Auto-generated method stub
		return mList.size();
	}

	@Override
	public Object getItem(int position) {//獲取數據集中與指定索引對應的數據項
		// TODO Auto-generated method stub
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {//獲取指定行對應的ID
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int arg0, View arg1, ViewGroup arg2) {//返回每一項的顯示內容
		// TODO Auto-generated method stub
		return null;
	}

}


上面最主要的是getView方法,還沒有實現,下面介紹getView方法實現的三重境界

 

1.逗比式

MyAdapter.java

 

package com.example.sr;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter {

	private List mList;
	private LayoutInflater minflater;//布局裝載器對象,用於把xml布局文件轉化為view
	
	
	public MyAdapter(Context context, List list){  //數據源與適配器進行了關聯
		mList = list;
		minflater = LayoutInflater.from(context);//context要使用當前的Adapter的界面對象
	}
	
	@Override
	public int getCount() { //返回ListView需要顯示的數據量
		// TODO Auto-generated method stub
		return mList.size();
	}

	@Override
	public Object getItem(int position) {//獲取數據集中與指定索引對應的數據項
		// TODO Auto-generated method stub
		return mList.get(position);
	}

	@Override
	public long getItemId(int position) {//獲取指定行對應的ID
		// TODO Auto-generated method stub
		return position;
	}

	@Override
	public View getView(int postion, View convertView, ViewGroup parent) {//返回每一項的顯示內容
		// TODO Auto-generated method stub
		View view = minflater.inflate(R.layout.item, null);
		//第一個參數為 需要裝載到item.xml布局文件,第二個參數通常寫null
		
		ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);
		TextView title = (TextView)view.findViewById(R.id.tv_title);
		TextView content = (TextView)view.findViewById(R.id.tv_content);
		
		//將數據取出來賦給這三個控件
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		
		return view;
	}

}

 

回到MainActivity.java 建立listView與MyAdapter的聯系

MainActivity.java

 

package com.example.sr;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.ListView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List itemBeanList = new ArrayList();
        for(int i = 0; i < 20; i++){
        	itemBeanList.add(new ItemBean(R.drawable.ic_launcher, "我是標題"+i, "我是內容"+i));
        }
        
        //建立listView與MyAdapter的聯系
        ListView listView = (ListView) findViewById(R.id.lv_main);
        listView.setAdapter(new MyAdapter(this, itemBeanList));//第一個參數為context,第二個是數據源
        
    }
}

 

至此,運行程序,發現listView可以顯示我們想要的東西了。

\

 

 

為什麼式逗比式呢?listView有緩沖機制,但是在getView無視了緩沖機制,都通過創建一個新的view去設置空間,效率及其低下,完全沒有利用到listView的緩存機制。

2. 普通式

修改getView方法

 

	@Override
	public View getView(int postion, View convertView, ViewGroup parent) {//返回每一項的顯示內容
		// TODO Auto-generated method stub
		
		//逗比式開始----------
		//View view = minflater.inflate(R.layout.item, null);
		//第一個參數為 需要裝載到item.xml布局文件,第二個參數通常寫null
		/*
		ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);
		TextView title = (TextView)view.findViewById(R.id.tv_title);
		TextView content = (TextView)view.findViewById(R.id.tv_content);
		
		//將數據取出來賦給這三個控件
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		*/
		//逗比式結束-----------
		
		//普通式,參數中已經有了一個converView,考慮是否緩存過了,如果緩存過了,可以直接使用
		if(convertView == null){
			convertView = minflater.inflate(R.layout.item, null);
		}
		ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image);
		TextView title = (TextView)convertView.findViewById(R.id.tv_title);
		TextView content = (TextView)convertView.findViewById(R.id.tv_content);
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		
		return convertView;
	}

 

利用了ListView的緩存特性,如果沒有緩存才創建新的View,算入門,但是findViewById依然會浪費大量時間

3. 文藝式(最好的)

創建了一個內部類 ViewHolder ,它與view相關聯,並緩存item的組件,這樣給item設置內容的時候,不用再去findviewById, 直接在ViewHolder裡面取出來就行了。

 

	@Override
	public View getView(int postion, View convertView, ViewGroup parent) {//返回每一項的顯示內容
		// TODO Auto-generated method stub
		
		//逗比式開始----------
		//View view = minflater.inflate(R.layout.item, null);
		//第一個參數為 需要裝載到item.xml布局文件,第二個參數通常寫null
		/*
		ImageView imageView = (ImageView) view.findViewById(R.id.iv_image);
		TextView title = (TextView)view.findViewById(R.id.tv_title);
		TextView content = (TextView)view.findViewById(R.id.tv_content);
		
		//將數據取出來賦給這三個控件
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		*/
		//逗比式結束-----------
		
		
		//普通式,參數中已經有了一個converView,考慮是否緩存過了,如果緩存過了,可以直接使用---------
		/*
		 if(convertView == null){
			convertView = minflater.inflate(R.layout.item, null);
		}
		ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image);
		TextView title = (TextView)convertView.findViewById(R.id.tv_title);
		TextView content = (TextView)convertView.findViewById(R.id.tv_content);
		ItemBean bean = mList.get(postion);
		imageView.setImageResource(bean.ItemImageResid);
		title.setText(bean.Itemtitle);
		content.setText(bean.ItemContent);
		return convertView;
		*/
		//普通式結束-----------------
		
		ViewHolder viewHolder;
		if(convertView == null){
			viewHolder = new ViewHolder();
			convertView = minflater.inflate(R.layout.item, null);
			viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_image);//把控件保存在ViewHolder中
			viewHolder.title = (TextView)convertView.findViewById(R.id.tv_title);
			viewHolder.content = (TextView)convertView.findViewById(R.id.tv_content);
			convertView.setTag(viewHolder);//進行關聯,把它的控件保存在viewHolder中,避免了findviewbyid去實例化
		}else{
			viewHolder = (ViewHolder)convertView.getTag();
		}
		ItemBean bean = mList.get(postion);
		viewHolder.imageView.setImageResource(bean.ItemImageResid);
		viewHolder.title.setText(bean.Itemtitle);
		viewHolder.content.setText(bean.ItemContent);
		return convertView;
		
	}
	
	class ViewHolder{  //首先創建內部類
		public ImageView imageView;
		public TextView title;
		public TextView content;
	}

 

不僅利用了ListView的緩存,更通過ViewHolder類來實現顯示數據的視圖的緩存,避免多次通過findViewById尋找控件,這是最好的方法。

 

總結:

ViewHolder優化BaseAdapter的思路

--創建Bean對象,用於封裝數據

--創建MyAdapter(繼承BaseAdapter)在構造方法中初始化用於映射的數據List

--創建ViewHolder類,創建布局映射關系

--判斷ConverView,為空則創建,並設置Tag,否則通過tag來取出ViewHolder

--給ViewHolder中的控件設置數據

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved