Многослойный ExpandableListView

В настоящее время я работаю над проектом, в котором мне нужно что-то вроде следующего:

- MainGroup 1 (Expandable) - SubGroup 1 (Expandable) - SubSubGroup 1 (Expandable) - Child View - Child View - ... - SubSubGroup 2 (Expandable) - Child View - Child View - ... - SubGroup 2 (Expandable) - SubSubGroup 3 (Expandable) - Child View - ... - SubSubGroup 4 (Expandable) - Child View - ... - SubGroup 3 (Expandable) - Child View - ... - MainGroup 2 (Expandable) - ... 

В лучшем случае это будет ExpandableListView внутри ExpandableListView внутри ExpandableListView – так что 3 слоя ExpandableListView :

  • MainGroup будет содержать только другой ExpandableListView .
  • SubGroup будет содержать другой ExpandableListView за исключением двух последних, которые всегда будут дочерними ChildViews . (Я думаю, что эти два могут быть заменены только на SubSubGroup )
  • SubSubGroup будет иметь ChildViews .

Моя проблема в том, что я думаю, что я не понимаю основных принципов того, как макеты ExpandableListView дочерними. Я рассматривал такие примеры, но не могу разглядеть функциональность.

Я попробовал просто добавить ExpandableListView в качестве дочернего в другое, но что-то не работает, поскольку только первый элемент внутреннего ExpandableListView виден, если вы расширяете одну из внешних групп. Однако я могу установить высоту контейнера внешних групп вручную, чтобы сделать его достаточно большим, чтобы показать все элементы во внутреннем ExpandableListView . Чтобы быть оптимальным, расчет высоты должен, конечно, выполняться «на лету».

Итак, чтобы получить более солидные вопросы:

  • Может ли кто-нибудь дать мне объяснение «жизненного цикла ExpandableListView » (под этим я подразумеваю создание, повторное использование представлений, расширение / сбой слушателей), в том числе:
    • Как и когда ExpandableListView уведомляет о том, что ребенок расширен или скомпенсирован?
    • Как ExpandableListView знает, сколько места нужно сделать, чтобы все дети вписывались в контейнер группы?
  • Какая польза от использования ExpandableListView для создания выше, по сравнению с просто смешиванием моего собственного решения с использованием некоторых LinearLayouts и некоторых OnClickListeners ?

редактировать

Для моего последнего вопроса я мог бы заметить, что может быть где угодно от 1 до 20+ MainGroups .

Solutions Collecting From Web of "Многослойный ExpandableListView"

Прежде всего, позвольте мне порекомендовать вам сайт GrepCode . В нем есть источники классов Android SDK. Спасибо за них, я нашел базовые принципы AdapterViews (я дал вам ссылку на ExpandableListView, но лучше, если вы исследуете не только ее, но и его родителей-классов).

Теперь, ваши вопросы и мои ответы:

Как и когда ExpandableListView уведомляет о том, что ребенок расширен или скомпенсирован?

См. Метод handleItemClick (просмотр v, int position, long id)

Как ExpandableListView знает, сколько места нужно сделать, чтобы все дети вписывались в контейнер группы?

Я не очень хорошо разбирался в этом вопросе, но, насколько я знаю, это сделано методом requestLayout (). Также мы выяснили, что один прокручиваемый вид не может быть встроен в другой прокручиваемый вид. (Это широко известная ошибка: поставить ListView в ScrollView или ListView в ExpandableListView).

Какая польза от использования ExpandableListView для создания выше, по сравнению с просто смешиванием моего собственного решения с использованием некоторых LinearLayouts и некоторых OnClickListeners?

AdapterViews быстрее. Но ваша конструкция слишком сложна даже для ExpandableListView. Вы можете использовать 2 решения.

  1. Guru-solution: если вы профессионально разрабатываете свои собственные Views / ViewGroups с нуля (я имею в виду, вы понимаете методы requestLayout (), dispatchDraw () и т. Д.), Затем пишите свой собственный GrandExpandableListAdapter с 3 уровнями.
  2. Среднее решение: используйте ExpandableListAdapter для первых 2 уровней и используйте LinearLayouts для 3-го уровня.

Возможно, вы захотите проверить этот проект. Я не пробовал, но думаю, стоит попробовать. По умолчанию ExpanadableListView довольно ограничен, изначально разработанный для поддержки только двух уровней. Вы можете взломать его, чтобы заставить его поддерживать больше уровней, но это будет беспорядочно.

Несмотря на то, что это не полное решение, все же его 3-слойный расширяемый список. Таким образом, вы оставили вам, как вы его стиль.

Вот класс

 package com.custom.nagee; import android.app.ExpandableListActivity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ExpandableListView; import android.widget.LinearLayout; public class CustomemExpandible extends ExpandableListActivity{ LayoutInflater inflator; boolean flag = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); inflator = LayoutInflater.from(getApplicationContext()); setListAdapter(new MyAdapter()); } @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { if(flag){ v.findViewById(childPosition).setVisibility(View.VISIBLE); flag = false; return true; } v.findViewById(childPosition).setVisibility(View.GONE); flag = true; return true; } class MyAdapter extends BaseExpandableListAdapter{ @Override public Object getChild(int groupPosition, int childPosition) { return null; } @Override public long getChildId(int groupPosition, int childPosition) { return 0; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { LinearLayout linearLayout = (LinearLayout)inflator.inflate(R.layout.group, null); linearLayout.getChildAt(1).setId(childPosition); return linearLayout; } @Override public int getChildrenCount(int groupPosition) { return 2; } @Override public Object getGroup(int groupPosition) { return null; } @Override public int getGroupCount() { return 2; } @Override public long getGroupId(int groupPosition) { return 0; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { return ((LinearLayout)inflator.inflate(R.layout.group, null)); } @Override public boolean hasStableIds() { // TODO Auto-generated method stub return false; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } } } 

И здесь идет xml-файл

group.xml

 <?xml version="1.0" encoding="utf-8"?> 

 <TextView android:id="@+id/editText1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="@color/back" android:layout_marginLeft="30dip" android:text="DONE" > </TextView> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_marginLeft="30dip" android:visibility="gone" > <TextView android:id="@+id/editText2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="DONE"> </TextView> <TextView android:id="@+id/editText3" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="DONE" /> <TextView android:id="@+id/editText4" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="DONE" /> </LinearLayout> 

И это находится под цветной папкой для изменения цвета текста, ее осталось, вы даже можете изменить фон для улучшения внешнего вида.

back.xml

 <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="false" android:color="#808080"/> <item android:state_window_focused="false" android:color="#808080"/> <item android:state_pressed="true" android:color="#808080"/> <item android:state_selected="true" android:color="#000000"/> <item android:color="#FF0000"/> <!-- not selected --> </selector> 

надеюсь, что это работает…