Android Treeview - PullRequest
       11

Android Treeview

40 голосов
/ 17 июля 2010

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

Есть предложения?

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

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

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

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

Ответы [ 10 ]

17 голосов
/ 14 февраля 2015

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

  • Дерево N-уровня.

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

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

AndroidTreeView

14 голосов
/ 03 июля 2011

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

enter image description here

10 голосов
/ 01 апреля 2011

я решил это для себя, разместив в аналогичной теме: другая тема

enter image description here

6 голосов
/ 30 мая 2011

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

Наша реализация в проекте с открытым исходным кодом.

4 голосов
/ 27 марта 2015

Я нашел более легкое решение этой проблемы, так как я сам немного продвинулся в своих навыках кодирования.В моей ситуации мне потребовалось Windows-тематическое древовидное представление, которое после мозгового штурма я смог реализовать практически без какого-либо кодирования! и встроенную HTML-страницу для отображения пользовательского древовидного представления и использования супер удобного интерфейса связи JavaScript для получения выбора и кликов: Пример проверки концепции в блоге Android-er

С помощью этой возможности мы можем воспользоваться большой коллекцией фрагментов JS / CSS-контроля в Интернете. Тематический элемент управления jQuery TreeView в стиле Windows7 - jsTree

Множество возможностей и возможностей с Android, приятного кодирования!

3 голосов
/ 07 октября 2012

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

enter image description here

3 голосов
/ 01 февраля 2011

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

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

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

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

2 голосов
/ 28 января 2011

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

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

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

2 голосов
/ 28 января 2011
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;
    }
}

}

1 голос
/ 04 января 2011

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

private class ParentAndKids {Object parent;Массив детей;}

В этом случае у вашего адаптера будет массив объектов ParentAndKids, представляющих верхний слой.Вы добавляете и удаляете элементы списка в зависимости от того, какие родители были расширены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...