spotifyのようにExpandableListViewを作成しようとしています...しかし、LinearLayoutを無効にしてボタンのように機能させる方法がわかりません(リストを展開します)好きなものを説明する画像を作成しました。テキスト/画像(親)のクリックを通常の操作として処理できるようにしたいです。右ボタンをクリックすると、Spotifyのようにリストが展開されます...
これは、ListFragmentを拡張するChannelListからのonCreateです。フラグメントが呼び出されると、データが保存され、新しいアダプタが生成されます。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
m_ListView = new ExpandableListView(getActivity());
m_ListView.setId(Android.R.id.list);
m_ListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
m_ListView.setMultiChoiceModeListener(m_MultiChoiceModeListener);
m_ChannelListAdapter = new ChannelListAdapter(getActivity(), this);
m_ListView.setAdapter(m_ChannelListAdapter);
m_ListView.setGroupIndicator(null);
m_ListView.setOnGroupClickListener(this);
return m_ListView;
}
アダプタには、次のようなgetGroupViewメソッドがあります。
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
if (view == null)
{
view = inflater.inflate(R.layout.layout_channelwithimage, viewGroup, false);
}
TextView textView = (TextView) view.findViewById(R.id.labelwithimage);
textView.setText(getGroup(i).toString());
ImageButton imbu = (ImageButton) view.findViewById(R.id.imageButton);
//imbu.setOnClickListener(this);
imbu.setFocusable(false);
return view;
}
したがって、アダプタにImageButtonを登録すると、アダプタからonClickが呼び出されます。しかし、onClickでは、どのグループがクリックされたかわかりません...リスナーにボタンを登録しないと、ChannelListからonGroupClickが呼び出されません...
これは少し古い質問ですが、この答えは誰かを助けるかもしれません。
特定のButton
またはその他のView
をクリックしてグループを展開/折りたたむ場合は、AdapterクラスのgetGroupView
メソッドでそのボタンを取得する必要があります。次に、onClick
のButton
メソッドで、parent
をExpandableListView
にキャストするか、アダプターを作成するときにコンストラクターでリストの参照を渡します。
私は最初のアプローチを好みます。 TextView
が1つと矢印であるImageView
があると仮定した場合のコードを次に示します。矢印の状態の変更も追加しました。
@Override
public View getGroupView(final int groupPosition, final boolean isExpanded,
View convertView, final ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.left_drawer_list_group, parent, false);
}
TextView listHeaderText = (TextView) convertView
.findViewById(R.id.left_menu_list_header_text);
ImageView listHeaderArrow = (ImageView) convertView.findViewById(R.id.left_menu_list_header_arrow);
listHeaderText.setText(headerTitle);
//Set the arrow programatically, so we can control it
int imageResourceId = isExpanded ? Android.R.drawable.arrow_up_float : Android.R.drawable.arrow_down_float;
listHeaderArrow.setImageResource(imageResourceId);
listHeaderArrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isExpanded) ((ExpandableListView) parent).collapseGroup(groupPosition);
else ((ExpandableListView) parent).expandGroup(groupPosition, true);
}
});
return convertView;
}
さらに、onGroupClick
リスナーでの展開/折りたたみを無効にします。
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
//Do some other stuff, but you shall not expand or collapse
return true;
}
別の方法がありますが、かなり悪い方法です。それは、Adapter
を作成してExpandableListView
を設定するクラス内にAdapter
クラス全体をコピーすることです。しかし、そうしないでください。真剣に! ;)
過度にエレガントな解決策ではありませんが、それは私を助けました:
元のgroupIndicatorを保持しました。そのままの振る舞いが気に入りました。
GroupItemレイアウトでは、元のgroupIndicatorが引き続きクリックできるように、空のビューでスペースをブロックしただけです。
<LinearLayout>
....
<!--just dummy space underneath the default expand_collapse group icon - this way original expand collapse behavior is preserved on the icon-->
<View
Android:layout_width="25dp"
Android:layout_height="match_parent">
</View>
<!-- text view will have actionListener -->
<TextView
Android:id="@+id/category_name"
Android:layout_weight="1"
Android:layout_width="0dp"
Android:layout_height="match_parent"
.... />
....
</LinearLayout>
ExpandableListAdapterの作成中にcallBackオブジェクトに忍び込み、それをフックするよりも「category_name」をクリックします(子要素とグループ要素の両方)
public class ExpandableListAdapter extends BaseExpandableListAdapter {
public interface OnCategoryActionListener {
boolean onCategorySelected(long categoryId);
}
....
public ExpandableListAdapter(Activity context, Category rootCategory,
OnCategoryActionListener callBack) {
this.context = context;
this.rootCategory = rootCategory;
this.callBack = callBack;
}
....
@Override
public View getGroupView(final int groupPosition, boolean isExpanded, View
convertView, ViewGroup parent) {
String categoryName = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.category, null);
}
TextView item = (TextView) convertView.findViewById(R.id.category_name);
item.setTypeface(null, Typeface.BOLD);
item.setText(categoryName);
item.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
callBack.onCategorySelected(getGroupId(groupPosition));
}
});
.....
ここで行う必要があるのは、マスターフラグメントクラスでExpandableListAdapterを適切に初期化することだけです。
expListAdapter = new ExpandableListAdapter(getActivity(), this.rootCategory,
new OnCategoryActionListener());
expListView = (ExpandableListView) getActivity().findViewById(R.id.categories_list);
expListView.setAdapter(expListAdapter);