2010-07-17 2 views
35

Я знаю, что есть ExpandableListView, но он поддерживает только до 2 уровней. Мне нужен верный вертикальный список по дереву, по крайней мере, до 5 уровней (лучше - лучше).Android Treeview

Любые предложения?

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

Я вижу разговор об использовании пользовательского адаптера и установке отступов, основанных на уровне элементов.

У меня есть несортированный ArrayList объектов, у которых есть идентификатор и родительский идентификатор, и я динамически добавляю элементы в этот массив.

Может ли кто-нибудь дать мне несколько примеров того, как я могу это сделать?

+0

См. Ссылку для Моего проекта, где может быть достигнуто представление списка деревьев N-уровня. Https: //github.com/Jaldips/Android-MultilevelTreeListView –

ответ

5

Отвечая на мой собственный вопрос, так как мы реализовали это много месяцев назад.

Our implementation в проекте с открытым исходным кодом.

+0

ваша ссылка не работает. можете ли вы его обновить? или вы можете вставить код sudo здесь. –

+0

@ Mr.32 - есть некоторые проблемы с DNS, сайт скоро появится. Тем временем вы можете проверить зеркало на github: https://github.com/haxar/mangler/blob/master/android/src/org/mangler/android/ChannelList.java –

+0

+1 для быстрого ответа ...! !!! –

1

Я бы начал с того, что структура данных более представила то, что она должна содержать. Поскольку у вас есть массив элементов, и каждый ребенок может иметь собственный массив элементов, каждый со своим собственным массивом и т. Д. Я бы подумал об использовании класса с двумя членами: объекта, который представляет данные для этого конкретного элемента и массива который содержит детей элемента. Каждый ребенок сам был бы экземпляром класса, чтобы у него тоже могли быть дети.

частный класс ParentAndKids { Object parent; Array kids; }

Ваш адаптер будет иметь массив объектов ParentAndKids, который представляет верхний слой. Вы должны добавлять и удалять элементы списка, на основе которых были расширены родители.

1
package com.expand.search; 

import android.app.ExpandableListActivity; 
import android.os.Bundle; 
import android.view.ContextMenu; 
import android.view.Gravity; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.ContextMenu.ContextMenuInfo; 
import android.widget.AbsListView; 
import android.widget.BaseExpandableListAdapter; 
import android.widget.ExpandableListAdapter; 
import android.widget.ExpandableListView; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.widget.ExpandableListView.ExpandableListContextMenuInfo; 

    /** Demonstrates expandable lists using a custom {@link ExpandableListAdapter} 
    * from {@link BaseExpandableListAdapter}. 
    */ 
public class expands extends ExpandableListActivity { 

ExpandableListAdapter mAdapter; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // Set up our adapter 
    mAdapter = new MyExpandableListAdapter(); 
    setListAdapter(mAdapter); 
    registerForContextMenu(getExpandableListView()); 
} 

@Override 
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 
    menu.setHeaderTitle("Sample menu"); 
    menu.add(0, 0, 0, R.string.expandable_list_sample_action); 
} 

@Override 
public boolean onContextItemSelected(MenuItem item) { 
    ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo(); 

    String title = ((TextView) info.targetView).getText().toString(); 

    int type = ExpandableListView.getPackedPositionType(info.packedPosition); 
    if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { 
     int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); 
     int childPos = ExpandableListView.getPackedPositionChild(info.packedPosition); 
     Toast.makeText(this, title + ": Child " + childPos + " clicked in group " + groupPos, 
       Toast.LENGTH_SHORT).show(); 
     return true; 
    } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { 
     int groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition); 
     Toast.makeText(this, title + ": Group " + groupPos + " clicked", Toast.LENGTH_SHORT).show(); 
     return true; 
    } 

    return false; 
} 

/** A simple adapter which maintains an ArrayList of photo resource Ids. 
* Each photo is displayed as an image. This adapter supports clearing the 
* list of photos and adding a new photo. 
*/ 
public class MyExpandableListAdapter extends BaseExpandableListAdapter { 
    // Sample data set. children[i] contains the children (String[]) for groups[i]. 
    private String[] groups = { "Category1", "Category2", "Category3", "Category4" }; 
    private String[][] children = { 
      { "Charity1", "Charity2", "Charity3", "Charity4" }, 
      { "Charity5", "Charity6", "Charity7", "Charity8" }, 
      { "Charity9", "Charity10" }, 
      { "Charity11", "Charity12" } 
    }; 

    public Object getChild(int groupPosition, int childPosition) { 
     return children[groupPosition][childPosition]; 
    } 

    public long getChildId(int groupPosition, int childPosition) { 
     return childPosition; 
    } 

    public int getChildrenCount(int groupPosition) { 
     return children[groupPosition].length; 
    } 

    public TextView getGenericView() { 
     // Layout parameters for the ExpandableListView 
     AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
       ViewGroup.LayoutParams.MATCH_PARENT, 64); 

     TextView textView = new TextView(expands.this); 
     textView.setLayoutParams(lp); 
     // Center the text vertically 
     textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); 
     // Set the text starting position 
     textView.setPadding(36, 0, 0, 0); 
     return textView; 
    } 

    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, 
      View convertView, ViewGroup parent) { 
     TextView textView = getGenericView(); 
     textView.setText(getChild(groupPosition, childPosition).toString()); 
     return textView; 
    } 

    public Object getGroup(int groupPosition) { 
     return groups[groupPosition]; 
    } 

    public int getGroupCount() { 
     return groups.length; 
    } 

    public long getGroupId(int groupPosition) { 
     return groupPosition; 
    } 

    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, 
      ViewGroup parent) { 
     TextView textView = getGenericView(); 
     textView.setText(getGroup(groupPosition).toString()); 
     return textView; 
    } 

    public boolean isChildSelectable(int groupPosition, int childPosition) { 
     return true; 
    } 

    public boolean hasStableIds() { 
     return true; 
    } 
} 

}

+2

здесь мы можем делать вложенность более 2 раз .. ?? –

2

Я согласен с PJV, по крайней мере, для устройств телефон размера. Было бы лучше организовать виджет, чтобы показывать одну группу братьев и сестер за раз в ListView. Это можно сделать в одном действии, которое отслеживает его положение в дереве. Он может отображать заголовок с панировочными сухарями, показывающий путь к родительскому элементу, отображаемому в настоящее время.

Многоуровневое древовидное представление может быть подходящим для планшетного устройства, но на телефоне недостаточно недвижимости для поддержки предлагаемых 5 уровней (при этом все должно быть достаточно большим для пальцев).

Тем не менее, если вы настроены на древовидную структуру, не смотрите на подклассу ExpandableListView. Он работает внутренне, упаковывая родительский и дочерний индексы (каждый int) в один длинный. Это внутреннее представление делает невозможным выходить за пределы двух уровней.

3

Я нашел ссылку ниже очень и очень полезную. В нем описаны альтернативные способы хранения древовидных структур в двухмерных структурах данных (обычно это таблица базы данных).

Я думаю, что парадигму можно легко понять и реализовать.

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

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

+0

Большое вам спасибо за пересмотр ссылки @Jarrod Dixon! С тех пор, как Oracle удалил (изначально) свободно доступный ресурс знаний (исходя из разработчиков MySQL, MySQL позже был куплен Sun, который, в свою очередь, к сожалению, если вы спросите меня, был куплен Oracle), я потратил приличное количество времени, чтобы найти альтернативный ресурс для него (очевидно, не «респектабельный промежуток времени»). Еще раз спасибо! – dbm

9

я решил это для меня, размещение в аналогичной теме: other thread

enter image description here

+1

Можете ли вы дать свое демо? – pengwang

13

Наша компания также открыла для этого решение. Он доступен в библиотеке, поэтому очень прост в использовании: http://code.google.com/p/tree-view-list-android/

enter image description here

+1

В вашем проекте с открытым исходным кодом нет ссылки для скачивания –

3

Я думаю, если многоуровневая expandablelist сделана правильно это на самом деле работает и выглядит великолепно. Вот еще один пример http://code.google.com/p/tree-view-list-android/

enter image description here

+0

Hi dotsa! Я пытаюсь реализовать это treeview из кода google. Поскольку вы уже внедрили его, можете ли вы мне помочь в решении некоторых вопросов? Если все в порядке, пожалуйста, позвоните мне на [email protected] Благодаря ! –

15

Я была такая же проблема. Вы можете проверить мою реализацию AndroidTreeView.

  • Его N-уровня дерева.

  • Пользовательский стиль для узлов

  • Сохранить состояние после вращения

AndroidTreeView

+0

Спасибо, полезно, можно добавить уровень с горизонтальными значками, – Anup

+1

Можете ли вы динамически изменить представление? В частности, если я изначально создаю дерево, содержащее узел конечной точки (листа), могу ли я потом изменить его на папку? – FractalBob

3

Я нашел легче решение этой проблемы, так как я сам несколько промежуточный в мои навыки кодирования. В моей ситуации мне понадобился Windows-themed Tree View, который после мозгового штурма идеи я смог реализовать с почти никакой кодировкой!

Вот трюк: использовать WebView и встроенный HTML-страницу для отображения пользовательского Tree View, и использовать супер удобный интерфейс Андроида связи JavaScript, чтобы получить выбор & кликов: Proof of Concept Example on Android-er Blog

С этой силой мы можем принять преимущество большой коллекции JS/CSS элементов управления по всему Интернету. Themeable Windows7-Style jQuery TreeView control -- jsTree

Лот возможностей и мощности с Android там, счастливое кодирование!