想要讓 ListView 顯示比較複雜的樣子,可以利用自訂 Adapter 的方式來達到目的。
1、首先先建立一個 list_view_item.xml,把每個項目要顯示的樣子先設定好。
list_view_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" android:orientation="vertical"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:gravity="left" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/ListItem_date" android:layout_width="250px" android:layout_height="wrap_content" android:layout_weight="6" android:textSize="21dip" android:textStyle="bold" android:textColor="#FF00FF00" ></TextView> </RelativeLayout> <RelativeLayout android:gravity="right" android:layout_weight="1" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/ListItem_company" android:layout_width="150px" android:layout_height="wrap_content" android:layout_weight="4" android:textSize="18dip" android:textStyle="bold" android:textColor="#FF0000" ></TextView> </RelativeLayout> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:gravity="left" android:layout_weight="2" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/ListItem_money" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12dip" android:textColor="#AAAAAA" ></TextView> </RelativeLayout> <RelativeLayout android:gravity="right" android:layout_weight="2" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/ListItem_miles" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12dip" android:textColor="#AAAAAA" ></TextView> </RelativeLayout> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content"> <RelativeLayout android:gravity="left" android:layout_weight="2" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/ListItem_price_per_litre" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12dip" android:textColor="#AAAAAA" ></TextView> </RelativeLayout> <RelativeLayout android:gravity="center" android:layout_weight="2" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/ListItem_price_per_mile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12dip" android:textColor="#AAAAAA" ></TextView> </RelativeLayout> <RelativeLayout android:gravity="right" android:layout_weight="2" android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/ListItem_miles_per_litre" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="12dip" android:textColor="#AAAAAA" ></TextView> </RelativeLayout> </LinearLayout> </LinearLayout>
當然,也要設定一個包含 ListView 的 xml 檔給 Activity 使用。
list_iew.xml
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
2、Adapter 本身要 extends BaseAdapter,內容最主要是設定 getView( ) 函式去決定 ListView 的項目該怎麼顯示,而資料的提供來源是一個 ArrayList<HashMap<String, String>> 型態的物件,也就是一個 ArrayList 的每個項目都是 HashMap,而每個 HashMap 都包含 String, String 兩個字串。
ListViewItem.java
import java.util.ArrayList; import java.util.HashMap; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class OilListAdapter extends BaseAdapter { private ArrayList<HashMap<String, String>> data; private LayoutInflater layoutInflater; public OilListAdapter (Context context, ArrayList<HashMap<String, String>> dt) { this.data = dt; this.layoutInflater = LayoutInflater.from(context); // 取得 LayoutInflater } public int getCount() { return this.data.size(); } public Object getItem(int position) { // TODO Auto-generated method stub return this.data.get(position); } public long getItemId(int arg0) { return 0; } public View getView(int position, View view, ViewGroup parent) { // TODO Auto-generated method stub if(view == null) // 設定 ListView 的 item 要使用的 View view = this.layoutInflater.inflate(R.layout.list_item, null); // 讀取要顯示的 TextView TextView date = (TextView) view.findViewById(R.id.OilListItem_date); TextView company = (TextView) view.findViewById(R.id.ListItem_company); TextView miles = (TextView) view.findViewById(R.id.ListItem_miles); TextView money = (TextView) view.findViewById(R.id.ListItem_money); TextView milesPerLitre = (TextView) view.findViewById(R.id.ListItem_miles_per_litre); TextView pricePerLitre = (TextView) view.findViewById(R.id.ListItem_price_per_litre); TextView pricePerMile = (TextView) view.findViewById(R.id.ListItem_price_per_mile); // 填入項目的內容 date.setText(this.data.get(position).get("refuel_date")); company.setText(this.data.get(position).get("refuel_company")); miles.setText(this.data.get(position).get("refuel_miles")+"公里"); money.setText(this.data.get(position).get("refuel_price")+"元"); pricePerLitre.setText("油價:"+getPricePerLitre(position, arith)+"元/公升"); //油價 pricePerMile.setText(getPricePerMile(position, arith)+"元/公里"); // 單位油價 milesPerLitre.setText(getAvgOfMilesPerLitre(position, arith)+"公里/公升"); //本次油耗 return view; } }
3、 設定好 Adapter 之後,要在程式中設定 ListView 要以這個 Adapter 作為資料存取的來源。
ListActivity.java
public class RecordList extends ListActivity { private ListView List; private ListAdapter ListAdapter; private ArrayList<HashMap<String, String>> ListArray; // ListView 的項目清單 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list_view); this.List = this.getListView(); this.setListView(); } //----------------------------------------------------------// //------------------------ ListView ------------------------// //----------------------------------------------------------// private void setListView () { // 設定 ListView 的 Adapter this.ListArray = new ArrayList<HashMap<String, String>>(); this.ListAdapter = new ListAdapter(this, this.ListArray); this.List.setAdapter(this.ListAdapter); this.updateRecordList(); } //------------------------------------------------------------------// //------------------------ update functions ------------------------// //------------------------------------------------------------------// /** * 更新列表內容 */ private void updateRecordList () { this.ListArray.clear(); SQLiteDatabase db = this.openOrCreateDatabase(db_name, Context.MODE_PRIVATE, null); String sql = "SELECT * FROM table"; Cursor cs = db.rawQuery(sql, null); HashMap<String, String> hm; int numOfRows = cs.getCount(); cs.moveToFirst(); for(int i=0 ; i<numOfRows ; i++) { hm = new HashMap<String, String>(); hm.put("refuel_id", cs.getString(0)); hm.put("refuel_company", cs.getString(2)); // 廠商名稱 hm.put("refuel_amount", cs.getString(3)); // 加油量 hm.put("refuel_miles", cs.getString(4)); // 里程 hm.put("refuel_price", cs.getString(5)); // 加油金額 hm.put("refuel_date", cs.getString(6)); // 加油日期 this.ListArray.add(hm); cs.moveToNext(); } db.close(); this.ListAdapter.notifyDataSetChanged(); } }
其中 updateRecordList() 這個函式是我設定來更新資料的,動作是從資料庫讀取資料後,填到 ArrayList<HashMap<String, String>> 裡,然後通知 Adapter 資料有更新。
沒有留言:
張貼留言