1. ArrayAdapter を継承した FavoriteAdapter
- FavoriteAdapter は任意の型のデータを取りうる
- その型のデータに対する date(T), balance(T) の実装が必要
- abstract class FavoriteAdapter<T>(context: Context, objects: List<T>)
- : ArrayAdapter<T>(context, 0, objects) {
- abstract fun date(data: T): String
- abstract fun balance(data: T): Int
- private val inflater = LayoutInflater.from(context)
- override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
- val view: View = convertView ?: ItemViewHolder
- .create(inflater, parent)
- .also { it.view.tag = it }
- .view
- getItem(position)?.let {
- (view.tag as ItemViewHolder).bind(date(it), balance(it))
- }
- return view
- }
- }
- CursorAdapter は任意の型のデータを取りうる
- その型のデータに対する date(T), balance(T) の実装が必要
- BaseData からその型のデータに変換するメソッドの実装が必要
- abstract class HistoryAdapter<T>(context: Context)
- : CursorAdapter(context, null, 0) {
- abstract fun date(data: T): String
- abstract fun balance(data: T): Int
- abstract fun create(data: BaseData): T
- private val inflater: LayoutInflater = LayoutInflater.from(context)
- override fun newView(context: Context, c: Cursor, parent: ViewGroup) {
- return ItemViewHolder.create(inflater, parent).also { it.view.tag = it }.view
- }
- override fun bindView(view: View, context: Context, c: Cursor) {
- val baseData = convert(c)
- val data = create(baseData)
- (view.tag as ItemViewHolder).bind(date(data), balance(data))
- }
- private fun convert(c: Cursor): BaseData {
- ...
- }
- }
Delegation なし
データとして MyData をとる Adapter を用意してみましょう。- class MyDataAdapter(context: Context, objects: List<MyData>)
- : FavoriteAdapter<MyData>(context, objects) {
- override fun date(data: MyData) =
- DateFormat.format(context.getString(R.string.format_date), data.getDate()).toString()
- override fun balance(data: MyData) = data.getBalance()
- }
- class MyDataAdapter(context: Context) : HistoryAdapter<MyData>(context) {
- override fun date(data: MyData) =
- DateFormat.format(context.getString(R.string.format_date), data.getDate()).toString()
- override fun balance(data: MyData) = data.getBalance()
- override fun create(data: BaseData): MyData = MyData(data)
- }
- val adapter: FavoriteAdapter<*> = MyDataAdapter(context, list)
- val adapter: HistoryAdapter<*> = MyDataAdapter(context)
そこで、まずは通常の Delegation パターンで実装してみます。
Delegation パターン
Adapter<T> インターフェースを用意し、FavoriteAdapter と HistoryAdapter に abstract で定義していたメソッドを Adapter のメソッドに置き換えます。- interface Adapter<T> {
- fun date(data: T): String
- fun balance(data: T): Int
- fun create(data: BaseData): T
- }
- class FavoriteAdapter<T>(context: Context, objects: List<T>, private val adapter: Adapter<T>)
- : ArrayAdapter<T>(context, 0, objects) {
- fun date(data: T): String = adapter.date(data)
- fun balance(data: T): Int = adapter.balance(data)
- ...
- }
- class HistoryAdapter<T>(val context: Context, private val adapter: Adapter<T>)
- : CursorAdapter(context, null, 0) {
- fun date(data: T): String = adapter.date(data)
- fun balance(data: T): Int = adapter.balance(data)
- fun create(data: BaseData): T = adapter.create(data)
- ...
- }
- class MyDataAdapter(private val context: Context) : Adapter<MyData> {
- override fun date(data: MyData) =
- DateFormat.format(context.getString(R.string.format_date3), data.getDate()).toString()
- override fun balance(data: MyData) = data.getBalance()
- override fun create(data: BaseData): MyData = MyData(data)
- }
- val adapter: FavoriteAdapter<*> = FavoriteAdapter(context, list, MyDataAdapter(context))
- val adapter: HistoryAdapter<*> = HistoryAdapter(context, MyDataAdapter(context))
一方、FavoriteAdapter と HistoryAdapter の date() や balance() メソッドでは、Adapter のメソッドをそのまま呼び出しているだけです。
Class Delegation を使うと、このような明示的な記述をしなくてよくなります。
Class Delegation
FavoriteAdapter と HistoryAdapter も Adapter<T> を実装し、by を使ってコンストラクタでもらった adapter に処理を委譲します。- class FavoriteAdapter<T>(context: Context, objects: List<T>, private val adapter: Adapter<T>)
- : ArrayAdapter<T>(context, 0, objects), Adapter<T> by adapter {
- ...
- }
- class HistoryAdapter<T>(val context: Context, private val adapter: Adapter<T>)
- : CursorAdapter(context, null, 0), Adapter<T> by adapter {
- ...
- }
0 件のコメント:
コメントを投稿