RelativeLayout を継承する他の複合コントロール (BaseControl) のベースとして機能するカスタム コントロールがあります。この BaseControl は、各コントロールの XML の拡張を簡素化し、その後それらを初期化することを目的としています。すべてはコンストラクターで行われます。
abstract class BaseControl extends RelativeLayout {
public BaseControl(Context context) {
super(context);
this.baseInitializeControl(context, null);
}
public BaseControl(Context context, AttributeSet attrs) {
super(context, attrs);
this.baseInitializeControl(context, attrs);
}
public BaseControl(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.baseInitializeControl(context, attrs);
}
private void baseInitializeControl(Context context, AttributeSet attrs) {
int layoutId = this.getControlLayoutId();
if(layoutId != 0) {
LayoutInflater inflater = LayoutInflater.from(getContext());
inflater.inflate(layoutId, this);
}
this.initializeControl(context, attrs);
}
protected abstract int getControlLayoutId();
protected abstract void initializeControl(Context context, AttributeSet attrs);
}
実際の問題は、OnItemClickedListener をコントロールの内部 ListView に設定したのに、どのクリックにも応答しないことです。この問題は、BaseControl クラスを抽象化する前にはありませんでした。onFinishInflate で ListView の setOnItemClickedListener メソッドを呼び出して、この問題を解決しました。
したがって、CustomList1 と CustomList2 があり、どちらも BaseControl を継承しています。CustomList1 には次のものがあります。
@Override
protected int getControlLayoutId() {
return R.layout.custom_list_1;
}
@Override
protected void initializeControl(Context context, AttributeSet attrs) {
this.mListView = this.findTypedViewById(R.id.listView);
CustomAdapter adapter = new CustomAdapter(getContext());
this.mListView.setAdapter(adapter);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
this.mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
HistoryGroupList.this.onListItemClicked(parentView, childView, position, id);
}
});
}
private void onListItemClicked(AdapterView<?> parentView, View childView, int position, long id) {
CustomAdapter adapter = (CustomAdapter) this.mListView.getAdapter();
CustomData data = adapter.getItem(position);
CustomList2 list = new CustomList2(getContext(), data); // CustomList2 should query more data here.
this.addView(list); // The new View is added in front of the current one
}
これまでのところ、最初の CustomList はクリックされた項目に応答し、新しいコントロール (2 つ目のリスト ビューを含む) を作成して前面に表示します。
2 番目のコントロール (CustomList2) はほぼ同じコードで、getControlLayoutId() で異なる ID を返すだけで、onListItemClicked(...) で Toast を表示し、コンストラクターの 2 番目のパラメーターを使用して別のアダプターを作成します。問題は、この 2 番目のコントロールが onFinishInflate() イベントを実行していないことですが、BaseControl で xml をインフレートしています。このコントロールを XML タグとして別のレイアウトに追加すると、onFinishInflate() メソッドが正常に実行されます。
このメソッドが実行されていない理由を知っていますか? あるいは、setOnItemClickedListener メソッドで問題を解決するための回避策かもしれません。
ありがとう!マイク