Отображение рекурсивных списков внутри вкладки

Вопрос по алгоритму здесь.

Я создаю приложение, которое показывает юридический документ с вкладками для навигации (оглавление, закладки и т. д.). Внутри вкладки TOC мне нужно показать многоуровневое оглавление. На «листе» toc мне нужно показать TextView

Итак, я мог бы:

tab1: Список -> Список -> Список -> Список -> Список -> TextView

or

tab1: Список -> Список -> Список -> TextView

or

tab1: Список -> TextView

в зависимости от главы, раздела, подраздела, структуры подраздела книги, которую я показываю.

Теперь, неважно, насколько глубоко вы находитесь, TabHost должен ВСЕГДА ПРИСУТСТВОВАТЬ, чтобы обеспечить основную навигацию. (Да, я просил, и мне нужно использовать вкладки, а не меню.)

Вопрос:

Как реализовать рекурсивный список внутри FrameLayout вкладки? Или я должен использовать ListView в стиле вкладок и просто не использовать TabHost?

Идеи?

Спасибо!
llappall


person llappall    schedule 21.03.2011    source источник


Ответы (1)


Хорошо. Во-первых, вы не можете поместить ListViews внутри ListViews, ScrollViews, GridViews или чего-либо, что можно прокручивать в этом отношении (т. е. элемент ListView не может быть ListView). Он может скомпилироваться, может запуститься, но результаты будут не такими, как вы ожидаете или хотите. Это связано с тем, что ListView не может иметь высоту, установленную на WRAP_CONTENT.

У вас может быть двухуровневый список (ExpandableListView), но если вам требуется больше уровней, вам придется реализовать функциональность самостоятельно, расширив ListView или ExpandableListView.

У вас также могут быть секционированные списки и списки с несколькими типами элементов, но нет возможности использовать компоненты SDK по умолчанию для получения 5-уровневого списка.

Номер два: Да, вы можете иметь ListView внутри TabHost. Вы не сможете использовать ListActivity, но это просто означает, что вам придется напрямую вызывать методы ListView:

ListView myList = findViewById(R.id.myList);
myList.setAdapter(myListAdapter);

вместо вызова встроенных методов ListActivity.

Просто поместите ListView внутри FrameLayout в файле макета. Если у вас есть три вкладки и ListView является первым элементом внутри FrameLayout, то он будет отображаться как содержимое первой вкладки. Если это второй элемент, он будет содержимым для второй вкладки и так далее.

Единственный способ реализовать рекурсивный список со встроенными компонентами — это использовать один ListView, а затем изменять содержимое адаптера ListView, когда пользователь выбирает элемент (по сути, раскрывающееся меню с использованием одного ListView). Вам также нужно было бы поймать кнопку «Назад» с помощью onBackPressed, чтобы пользователь мог вернуться вверх по списку или предоставить кнопку «Назад» где-нибудь.

person Joseph Earl    schedule 21.03.2011
comment
Иосиф, спасибо за ответ. Это именно то, что я искал: никаких простых решений. Изменение ListView адаптером звучит как самое близкое к тому, что я хочу, но адаптер будет выглядеть чудовищно. Спасибо! --Ллапполл - person llappall; 22.03.2011
comment
Не обязательно. Например, в простом случае, если у вас есть одно меню верхнего уровня с 4 меню второго уровня, вам просто понадобятся ArrayAdapter‹String›, List‹String› и 5 String[] (содержащие верхнее меню и 4 подменю) и целое число для запоминания текущего уровня. Просто вызовите List.clear(), затем List.addAll(String[]) с одним из ваших наборов данных, затем ArrayAdapter.notifyDatasetChanged() и содержимое вашего списка изменится. Используйте onClickListener в своем списке и в методе onClick решите, ведет ли этот элемент в подменю (в этом случае загрузите требуемый набор данных) или нет (выполните действие элемента) - person Joseph Earl; 22.03.2011
comment
На самом деле вы можете создать ArrayAdapter‹MyObject›, где MyObject будет выглядеть примерно так: class MyObject { public String itemName; public List<MyObject> childItems; }. Затем, когда элемент щелкнут, проверьте, ((MyObject) ListView.getItemAtPosition(position)).childItems == null. Если нет, установите childItems в качестве нового содержимого адаптера. Таким образом, вам нужно отслеживать только один родительский список «Мой объект», но вам нужно будет как-то настроить его в первую очередь. - person Joseph Earl; 22.03.2011
comment
Еще один комментарий: чтобы сделать «лист», который будет представлять собой другой вид (скажем, LinearLayout с двумя TextView), я мог бы иметь как ListView, так и этот вид внутри FrameLayout и вызвать setVisibility (Visibility.GONE) для того, кто мне не нужен. Звучит так выполнимо... :) - person llappall; 22.03.2011
comment
Кстати, я очень ценю, что вы нашли время, чтобы помочь мне обдумать это. Ты крутой! - person llappall; 22.03.2011