Selasa, 18 Januari 2011

オブジェクト指向な ListView の使い方(前編)

以下のような ListView のサンプルがあったとします。
package com.blogspot.androlab.example;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;

/** メインアクティビティです。 */
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

List<Schedule> scheduleList = new ArrayList<Schedule>();

// リストに値を挿入
scheduleList.add(new Schedule("2011/01/19", "通常業務", "業務報告", "懇談会"));
scheduleList.add(new Schedule("2011/01/20", "通常業務", "業務報告"));
scheduleList.add(new Schedule("2011/01/21", "通常業務", "週末報告", "日本 vs カタール"));
scheduleList.add(new Schedule("2011/01/24", "朝礼", "工場視察"));

// リストに表示する文字列を配列に格納
List<String> sList = new ArrayList<String>(scheduleList.size());
for (Schedule s : scheduleList)
sList.add(s.getDateString() + " [ " + s.size() + "件 ]");

// 作成した配列で ArrayAdapter を作成
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, sList);

// ListView を作成
ListView listView = new ListView(this);
listView.setAdapter(arrayAdapter);

// レイアウト
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.addView(listView, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
setContentView(linearLayout);
}
}

/** 日程クラスです。 */
class Schedule extends ArrayList<Task> {
private static final long serialVersionUID = 1L;
private Date mDate;
Schedule(String date, String... tasks) {
mDate = new Date(date);
for (String task : tasks) add(new Task(task));
}
String getDateString() {
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.JAPANESE);
return df.format(mDate);
}
}

/** 仕事の最小単位です。 */
class Task {
private String mSubject;
Task(String subject) {
mSubject = subject;
}
public String toString() {
return mSubject;
}
}

実行結果

スケジュールの日にち(Schedule#getDateString())と件数(Schedule#size())が、一行づつ出力されています。
このほかに、内容(Task t = Schedule#get(n))を含めて表示させたいときは、どうしたらよいでしょうか。

強引に30行目付近を、
sList.add(s.getDateString() + " [ " + s.size() + "件 ]\n" + s.get(0) + ", " + s.get(1));
のようにして、文字列を連結してしまうことも可能ですが、ちょっとかっこ悪いですよね。

こういうときは、ArrayAdapter#getView(int, View, ViewGroup) をオーバライドして対応させると、非常にスマートになります。

package com.blogspot.androlab.example;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.TwoLineListItem;

public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

List<Schedule> scheduleList = new ArrayList<Schedule>();

// リストに値を挿入
scheduleList.add(new Schedule("2011/01/19", "通常業務", "業務報告", "懇談会"));
scheduleList.add(new Schedule("2011/01/20", "通常業務", "業務報告"));
scheduleList.add(new Schedule("2011/01/21", "通常業務", "週末報告", "日本 vs カタール"));
scheduleList.add(new Schedule("2011/01/24", "朝礼", "工場視察"));

// 作成した配列で ArrayAdapter を作成
ArrayAdapter<Schedule> arrayAdapter = new ArrayAdapter<Schedule>(this, 0, scheduleList) {
private LayoutInflater mInflater;
// 初期化子(コンストラクタの代わり)
{
mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
}
// 表示する「一行分のView」を返すメソッド
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 表示する一行分のViewには、android.R.layout.simple_list_item_2
// (中身は TwoLineListItem) を利用する
Schedule s = getItem(position);
TwoLineListItem view = (TwoLineListItem) mInflater.inflate(android.R.layout.simple_list_item_2, null);

// 1/2行分のTextView(上部)
TextView text1 = view.getText1();
text1.setText(s.getDateString() + " [ " + s.size() + "件 ]");

// 1/2行分のTextView(下部)
TextView text2 = view.getText2();
text2.setSingleLine(true);
String tasks = ""; for (Task t : s) tasks += t + ", ";
text2.setText(tasks.substring(0, tasks.length() - 2));

return view;
}
};

// ListView を作成
ListView listView = new ListView(this);
listView.setAdapter(arrayAdapter);

// レイアウト
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.addView(listView, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
setContentView(linearLayout);
}
}

/** 日程クラスです。 */
class Schedule extends ArrayList<Task> {
private static final long serialVersionUID = 1L;
private Date mDate;
Schedule(String date, String... tasks) {
mDate = new Date(date);
for (String task : tasks) add(new Task(task));
}
String getDateString() {
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.JAPANESE);
return df.format(mDate);
}
}

/** 仕事の最小単位です。 */
class Task {
private String mSubject;
Task(String subject) {
mSubject = subject;
}
public String toString() {
return mSubject;
}
}

実行結果

うまくいきました。
プログラムの保守性も考えて、なるべく、オブジェクト単位で処理していきたいですね。

次回は、リスト選択時のアイテムの扱い方をご紹介します。

Tidak ada komentar:

Posting Komentar

 
Copyright 2010 hot news. All rights reserved.
Themes by Ex Templates Blogger Templates l Home Recordings l Studio Rekaman Sitemap New gadget news Luxury Car Review Celebrity News Head Line News News Trends Concept cars Gambar Mesin Circuit Electronic Celebrity News Trends MotoGP News Trends Ghost Mistery Honda Modify Ghost photo Collection Credit Card Mstered Flower Colelction Photo Hybrid Auto News Modification Auto Indonesian News Trends Day News Trends Automotive News Trends vex robotic kit Hot News Trends