2012-07-20

Android列表(ListView)應用(二) - 自定義列表

列表(ListView)的應用上,很少是簡簡單單而已xd,很多都是要加東加西,又是加圖片

又是加標題、加內容的,所以事情很常不是我們想的那麼簡單的xd,這時就一定要用到

自定義這個東西,自定義顧名思義就是隨便您定,只要您高興、您開心,愛怎麼定都可以

方便是很方便,不過相對的會比較複雜一些,既然會需要用到,那我們就來看看怎麼做吧!


首先想要自定義的都需要多一個模板,所以新增一個List.xml

adapter.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal" 
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">
    <ImageView
        android:id="@+id/MyAdapter_ImageView_icon"
        android:layout_width="110dp"
        android:layout_height="70dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="5dp"
    />
 <LinearLayout android:orientation="vertical"
		android:layout_width="wrap_content" 
		android:layout_height="wrap_content">

     <TextView
         android:id="@+id/MyAdapter_TextView_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginLeft="20dp"
         android:textColor="#ffbf00" />
      
    <TextView
        android:id="@+id/MyAdapter_TextView_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:textColor="#FFFFFFFF" />

  </LinearLayout>  
</LinearLayout>


新增一個適配器,也是資料的橋接器MyAdapter,說明資料應該對應到模板的哪個位置
MyAdapter.java
package jim.demo.listview;

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 LayoutInflater myInflater;
    CharSequence[] title = null;
    CharSequence[] info = null;
    
    public MyAdapter(Context ctxt, CharSequence[] title, CharSequence[] info){
        myInflater = LayoutInflater.from(ctxt);
        this.title = title;
        this.info = info;
    }
    
	@Override
	public int getCount() {
		 return title.length;
	}

	@Override
	public Object getItem(int position) {
		 return title[position];
	}

	@Override
	public long getItemId(int position) {
		 return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		//自訂類別,表達個別listItem中的view物件集合。
        ViewTag viewTag;

        if(convertView == null){
            //取得listItem容器 view
            convertView = myInflater.inflate(R.layout.adapter, null);
            
            //建構listItem內容view
            viewTag = new ViewTag(
            (ImageView)convertView.findViewById(R.id.MyAdapter_ImageView_icon),
            (TextView) convertView.findViewById(R.id.MyAdapter_TextView_title),
            (TextView) convertView.findViewById(R.id.MyAdapter_TextView_info)
             );
            
            //設置容器內容
            convertView.setTag(viewTag);
        }
        else{
            viewTag = (ViewTag) convertView.getTag();
        }
        
        //設定內容圖案
        switch(position){
            case 0:
                viewTag.icon.setBackgroundResource(R.drawable.taipei);
                break;
            case 1:
                viewTag.icon.setBackgroundResource(R.drawable.taichung);
                break;
            case 2:
                viewTag.icon.setBackgroundResource(R.drawable.kaohsiung);
                break;
        }
        
        //設定標題文字
        viewTag.title.setText(title[position]);
        //設定內容文字
        viewTag.info.setText(info[position]);
        
        return convertView;
	}

	//自訂類別,表達個別listItem中的view物件集合。
    class ViewTag{
        ImageView icon;
        TextView title;
        TextView info;
    
        public ViewTag(ImageView icon, TextView title, TextView info){
            this.icon = icon;
            this.title = title;
            this.info = info;
        }
    }
}

再來當然是我們的主程式DemoListViewActivity
修改繼承自ListActivity,也可以不改變繼承,延用預設的Activity
只是還要用findViewById去找到該ListView再把資料載入而已
如果您的頁面上只是很單純的一個ListView,就直接用ListActivity會比較快

MyAdapter.java
package jim.demo.listview;

import android.app.ListActivity;
import android.os.Bundle;

public class DemoListViewActivity extends ListActivity {
    
	private String[] mtitle = new String[]{"台北","台中","高雄"} ;
	private String[] minfo =  new String[]{"台北101.故公博物院.中正記念堂","都會公園.高美濕地.大坑風景區","西子灣.英國領事館.愛河"};
	
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
                
        //標題資料
        CharSequence[] Mtitle = mtitle;
        //內容
        CharSequence[] Minfo = minfo;
        //載入列表中,new出MyAdapter時帶入所需"標題"."內容"資料
        setListAdapter(new MyAdapter(this, Mtitle, Minfo));
        
    }
}

執行後畫面

後記:

           自定義ListView的重點在於adapter.xml這個模板及MyAdapter.java這個適配器

只要修改模板及適配器就能做出自己想要的列表形式,這個對剛接觸android程式設計

的人來說可能會有點不太習慣這樣的設計模式,但android很多地方都是這種設計模式的

只要是自定義的地方,大多都會是此種形式,就為你介紹到此,謝謝。

2 則留言:

  1. 不好意思,我把三個程式碼都複製貼上,但是有錯,可以幫們一下嗎

    回覆刪除
  2. 原來是list的名字沒有改 android:id="@android:id/list" ,哈XD

    回覆刪除

您的寶貴建議是我前進的動力!