天天看點

android ListView的簡單使用與優化

ListView顧名思義是顯示清單的控件,幾乎每個App都會使用到ListView,當需要展示大量的資料時就需要用到ListView.在本文我會用ListView模仿虎撲做一個簡單的NBA球星得分排行榜

android ListView的簡單使用與優化

首先我們在布局檔案中定義一個ListView

<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"
    tools:context="${relativePackage}.${activityClass}" >
<ListView 
    android:id="@+id/second_listView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ></ListView>
</RelativeLayout>
           

layout_width和layout_height屬性都設為match_parent,使其占滿整個螢幕。

ListView是用來顯示資料的,這些資料可能從網上下載下傳,也可能從資料庫中讀取,在這裡我們采用寫死的方法來加載資料。

建立一個球星的類,屬性分别為姓名,資料,頭像資源ID,得分,所屬球隊

public class Person {
	
	private String mName;
	private String mData;
	private int mIcon;
	private String mScore;
	private String mTeam;
	
	public Person(String name, String data, int icon, String score, String team) {
		
		mName = name;
		mData = data;
		mIcon = icon;
		mScore = score;
		mTeam = team;
	}
	public String getName() {
		return mName;
	}
	public void setName(String name) {
		mName = name;
	}
	public String getData() {
		return mData;
	}
	public void setData(String data) {
		mData = data;
	}
	public int getIcon() {
		return mIcon;
	}
	public void setIcon(int icon) {
		mIcon = icon;
	}

	public String getScore() {
		return mScore;
	}
	public void setScore(String score) {
		mScore = score;
	}
	public String getTeam() {
		return mTeam;
	}
	public void setTeam(String team) {
		mTeam = team;
	}
	

           

建立每個item顯示的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
    <ImageView 
        android:layout_gravity="center"
        android:id="@+id/lead_icon_imageView"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/kobe"
        android:layout_margin="5dp"
        />
    <LinearLayout 
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        
        >
        <TextView 
            android:id="@+id/lead_name_TextView"
            android:layout_width="wrap_content"
            android:layout_weight="1"
            android:layout_height="0dp"
            
            android:gravity="center"
            android:textSize="18sp"
            />
        <TextView 
            android:id="@+id/lead_date_TextView"
            android:layout_marginTop="3dp"
            android:textSize="15sp"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_weight="1"
           
            android:gravity="center"
            />
        
        
    </LinearLayout>
    <LinearLayout 
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        >
        <TextView
            android:id="@+id/lead_team_TextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
           	android:textSize="18sp"
           	android:layout_marginLeft="55dp"
            
            />
    </LinearLayout>
      <LinearLayout 
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        >
        <TextView
            android:id="@+id/lead_score_TextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
          	android:layout_gravity="center_vertical"
           	android:textSize="18sp"
           	android:layout_marginLeft="30dp"
            
            />
    </LinearLayout>
    

</LinearLayout>
           

建立Adapter

資料是無法直接傳遞給ListView的,這時候就需要用到擴充卡即Adapter,我們建立一個StarAdapter使用ArrayAdapter作為基類,由于資料是Person類型的,泛型使用Person,定義一個mResourceId作為傳進來的每個Item的布局,重寫構造方法使其初始化。

該類的關鍵在于getView方法,這個方法會在每個子項被定義時調用。首先通過position擷取到子項,然後通過LayoutInflate轉化我們傳入的布局,然後擷取到每個控件,接着為其指派,最後将view傳回。

這個方法有兩個優化的地方

1、重用廢棄的view

convertView存放的是移除螢幕的view,如果我們每一個view都執行個體化,會極大的浪費記憶體,是以我們會先判斷一下convertView是否為空,如果為空就利用LayoutInflate進行轉化生成新的view,如果不為空直接使用廢棄的view。

2、使用ViewHolder

我們在每次getView方法中擷取控件時都需要使用findViewById,是以我們會增加建立一個類ViewHolder,裡面變量為子項所需要的控件,通過view.setTag将ViewHolder存儲在view中,如果convertView存在的話直接通過view.getTag方法擷取到ViewHolder,這樣會使ListView更加優化,提高流暢度。

public class StarAdapter extends ArrayAdapter<Person>{
	
	private int mResourceId;

	public StarAdapter(Context context, int resource, List<Person> objects) {
		super(context, resource, objects);
		mResourceId=resource;
	}
	
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// TODO Auto-generated method stub
		Person person=getItem(position);
		View view;
		ViewHolder viewHolder;
		if(convertView==null){
			viewHolder=new ViewHolder();
			view=LayoutInflater.from(getContext()).inflate(mResourceId, null);
			viewHolder.mIconImage=(ImageView) view.findViewById(R.id.lead_icon_imageView);
			viewHolder.mNameTextView=(TextView) view.findViewById(R.id.lead_name_TextView);
			viewHolder.mDataTextView=(TextView) view.findViewById(R.id.lead_date_TextView);
			viewHolder.mTeamTextView=(TextView) view.findViewById(R.id.lead_team_TextView);
			viewHolder.mScoreTextView=(TextView) view.findViewById(R.id.lead_score_TextView);
			//将viewHolder放在view中
			view.setTag(viewHolder);
			
		}else{
			view=convertView;
			//從view中擷取viewHolder
			viewHolder=(ViewHolder) view.getTag();
		}
		viewHolder.mIconImage.setImageResource(person.getIcon());
		viewHolder.mNameTextView.setText(person.getName());
		viewHolder.mDataTextView.setText(person.getData());
		viewHolder.mTeamTextView.setText(person.getTeam());
		viewHolder.mScoreTextView.setText(person.getScore());
		
		return view;
	}
	
	class ViewHolder{
		ImageView mIconImage;
		TextView mNameTextView;
		TextView mDataTextView;
		TextView mScoreTextView;
		TextView mTeamTextView;
	}
	

}
           

将擴充卡傳給ListView

首先初始化資料,我們将資料存到一個ArrayList<Person>中

private List<Person> stars=new ArrayList<Person>();
           
private void initStars(){
		Person durant=new Person("杜蘭特", "32.1分7闆5助", R.drawable.durant, "32.1", "雷霆");
		stars.add(durant);
		Person kobe=new Person("科比", "30.7分6闆6助", R.drawable.kobe, "30.7", "湖人");
		stars.add(kobe);
		Person lebron=new Person("詹姆斯", "26.9分8闆8助", R.drawable.lebron, "26.9", "騎士");
		stars.add(lebron);
		Person wade=new Person("韋德", "24.5分7闆4助", R.drawable.wade, "24.5", "熱火");
		stars.add(wade);
		Person jeremy=new Person("林書豪", "15.2分4闆8助", R.drawable.jeremy, "15.2", "黃蜂");
		stars.add(jeremy);
		Person durant2=new Person("杜蘭特", "32.1分7闆5助", R.drawable.durant, "32.1", "雷霆");
		stars.add(durant2);
		Person kobe2=new Person("科比", "30.7分6闆6助", R.drawable.kobe, "30.7", "湖人");
		stars.add(kobe2);
		Person lebron2=new Person("詹姆斯", "26.9分8闆8助", R.drawable.lebron, "26.9", "騎士");
		stars.add(lebron2);
		Person wade2=new Person("韋德", "24.5分7闆4助", R.drawable.wade, "24.5", "熱火");
		stars.add(wade2);
		Person jeremy2=new Person("林書豪", "15.2分4闆8助", R.drawable.jeremy, "15.2", "黃蜂");
		stars.add(jeremy2);
		Person durant3=new Person("杜蘭特", "32.1分7闆5助", R.drawable.durant, "32.1", "雷霆");
		stars.add(durant3);
		Person kobe3=new Person("科比", "30.7分6闆6助", R.drawable.kobe, "30.7", "湖人");
		stars.add(kobe2);
		Person lebron3=new Person("詹姆斯", "26.9分8闆8助", R.drawable.lebron, "26.9", "騎士");
		stars.add(lebron3);
		Person wade3=new Person("韋德", "24.5分7闆4助", R.drawable.wade, "24.5", "熱火");
		stars.add(wade3);
		Person jeremy3=new Person("林書豪", "15.2分4闆8助", R.drawable.jeremy, "15.2", "黃蜂");
		stars.add(jeremy3);
		
		
		
	}
           

為ListView設定擴充卡

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_second);
		
		
		initStars();
		
		mShowListView=(ListView) findViewById(R.id.second_listView);
		
		StarAdapter adapter=new StarAdapter(SecondActivity.this, R.layout.lead_item, stars);
		
		mShowListView.setAdapter(adapter);
		
	}
           

結束!這隻是簡單使用,ListView的使用太多變了,需要多多學習!