- Butter Knife
- ListViewのViewHolderパターン
- ListViewに複雑なHeader (もしくはFooter) を置きたい
- が、Activity/Fragmentに直接書いてしまうと見づらくなる、他の場所で再利用したいときも大変
- ViewHolderパターン的なものをつかってHeaderをクラスにする
- なおかつButter Knifeを使ってすっきり書く
- TextViewが2つ、Buttonが3つあるHeader
- TextViewの中身はあとで更新したりしたい(サーバから文字列を取得して表示したり)
- Buttonのクリックイベントを取得して何かしたい
public class ComplexHeaderHolder {
public interface HeaderListener {
public void onLeftButtonClick();
public void onMiddleButtonClick();
public void onRightButtonClick();
}
@InjectView(R.id.header_title)
public TextView title;
@InjectView(R.id.header_description)
public TextView description;
public View view;
private HeaderListener mListener;
public ComplexHeaderHolder(LayoutInflater inflater) {
view = inflater.inflate(R.layout.header, null);
ButterKnife.inject(this, view);
}
/** Listenerをセットする */
public void setListener(HeaderListener listener) {
mListener = listener;
}
@OnClick(R.id.header_button_left)
void onLeftButtonClick() {
if (mListener != null) {
mListener.onLeftButtonClick();
}
}
@OnClick(R.id.header_button_middle)
void onMiddleButtonClick() {
if (mListener != null) {
mListener.onMiddleButtonClick();
}
}
@OnClick(R.id.header_button_right)
void onRightButtonClick() {
if (mListener != null) {
mListener.onRightButtonClick();
}
}
}
Activity/Fragment側の実装
public class MainFragment extends Fragment
implements ComplexHeaderHolder.HeaderListener {
@InjectView(R.id.fragment_listview)
ListView mListView;
private ComplexHeaderHolder mHeaderHolder;
/** onCreateViewなどでのViewの初期化 */
private void setUpViews() {
// … 他のViewの初期化処理 …
// Headerをつくる
mHeaderHolder = new ComplexHeaderHolder(inflater);
// Listenerをセットする
mHeaderHolder.setListener(this);
// ListViewにHeaderを追加する
mListView.addHeaderView(mHeaderHolder.view, null, false);
mListView.setAdapter(adapter);
}
/** Headerのテキストをサーバから取得して表示したり */
private void setHeaderText() {
mHeaderHolder.title.setText("title");
mHeaderHolder.description.setVisibility(View.GONE);
}
@Override
public void onLeftButtonClick() {
// Headerの左ボタンがクリックされたとき
}
@Override
public void onMiddleButtonClick() {
// Headerの中ボタンがクリックされたとき
}
@Override
public void onRightButtonClick() {
// Headerの右ボタンがクリックされたとき
}
}
これで、Activity/Fragment側がすっきりして、ComplexHeaderHolderも他のActivity/Fragmentで簡単に再利用できるようになった。
ComplexHeaderHolderってカスタムのViewGroupでもいいんじゃないの?
いいと思います。
ComplexHeaderHolderってFragmentでもいいんじゃないの?
いいと思います。が、Fragmentにするのはなにか違和感があるような気がしなくもない