2010-07-17 14 views
35

Sé que es el ExpandableListView pero solo admite hasta 2 niveles. Necesito una verdadera lista vertical treeview con al menos hasta ~ 5 niveles (más es mejor).Android Treeview

¿Alguna sugerencia?

edición:

veo charla sobre el uso de un adaptador personalizado y establecer el relleno basado en el nivel de artículos.

Tengo una ArrayList no ordenada de objetos que tienen un ID y una identificación principal, y también dinámicamente agregué elementos a esta matriz.

¿Alguien me puede dar algunos ejemplos de cómo puedo hacer esto?

+0

Ver es el enlace para Mi proyecto en el que se puede lograr la vista de lista de N-Tree Tree.https: //github.com/Jaldips/Android-MultilevelTreeListView –

Respuesta

5

responder a mi propia pregunta, desde que implementamos esto hace muchos meses.

Our implementation en un proyecto de código abierto.

+0

su enlace no está funcionando. ¿Puedes actualizarlo? o puedes pegar algún código de sudo aquí ... –

+0

@ Mr.32 - hay algunos problemas de DNS, el sitio estará disponible pronto. En el mientras tanto se puede comprobar un espejo en github: https://github.com/haxar/mangler/blob/master/android/src/org/mangler/android/ChannelList.java –

+0

1 para una respuesta rápida ...! !!! –

1

Comenzaría haciendo que la estructura de datos sea más representativa de lo que debe contener. Ya que tiene una variedad de elementos y cada niño puede tener su propia matriz de elementos, cada uno con su propia matriz, etc. Consideraría usar una clase con dos miembros: un objeto que represente los datos de este elemento en particular y una matriz que contiene los hijos del objeto. Cada niño sería una instancia de la clase para que también pudiera tener hijos.

clase privada ParentAndKids { Objeto principal; Array kids; }

Su adaptador tendría una matriz de objetos ParentAndKids que representa la capa superior. Agregaría y eliminaría elementos de la lista según qué padres se expandieron.

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

aquí podemos hacer anidar más de 2 veces .. ?? –

2

Estoy de acuerdo con PJV, al menos para los dispositivos de teléfono de tamaño. Sería mejor organizar el widget para mostrar un grupo de hermanos a la vez en un ListView. Esto podría hacerse en una sola actividad que realiza un seguimiento de su posición en el árbol. Podría mostrar un encabezado con rutas de exploración que muestren la ruta al elemento principal de los elementos que se muestran actualmente.

Una vista de árbol de niveles múltiples puede ser apropiada para un dispositivo de tableta, pero un teléfono no tiene suficiente espacio para soportar los 5 niveles propuestos (con todo lo necesario para los dedos).

Sin embargo, si está configurado en una vista en árbol, no mire la subclase ExpandableListView. Funciona internamente al empacar los índices padre e hijo (cada uno int) en una sola longitud. Esta representación interna hace que sea virtualmente imposible extenderse más allá de 2 niveles.

3

Encontré el siguiente enlace muy, muy útil. Describe formas alternativas de almacenar estructuras de árbol en estructuras de datos bidimensionales (generalmente una tabla de base de datos).

Creo que encontrará que el paradigma es fácil de comprender e implementar.

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

A partir de la forma de visualizar esto en Android es otra cuestión. Tal vez escribiría mi propio widget desde cero si la solución de elementos de la lista "acolchada" no es suficiente.

+0

¡Muchas gracias por revisar el enlace @Jarrod Dixon! Desde que Oracle eliminó el recurso de conocimiento (originalmente) libremente disponible (que se origina en los desarrolladores de MySQL, MySQL fue comprado más tarde por Sun, quien a su vez, desafortunadamente, si me preguntas, fue comprado por Oracle). He gastado una cantidad respetable de tiempo para encontrar un recurso alternativo para ello (obviamente, no es una "cantidad respetable de tiempo" suficiente, sin embargo). ¡Gracias de nuevo! – dbm

13

Nuestra empresa también tiene una solución de código abierto para esto. Está disponible como biblioteca, de modo muy fácil de usar: http://code.google.com/p/tree-view-list-android/

enter image description here

+1

No hay ningún enlace de descarga en su proyecto de código abierto –

3

creo que si expandablelist multinivel se hace correctamente lo que realmente funciona y se ve muy bien. Aquí es otro ejemplo de http://code.google.com/p/tree-view-list-android/

enter image description here

+0

Hola dotsa! Estoy tratando de implementar esta vista de árbol desde el código de google. Como ya lo implementó, ¿me puede ayudar con algunos problemas con respecto a esto? Si está bien, por favor llámame a [email protected] Gracias ! –

15

que tenía el mismo problema. Puede consultar mi implementación AndroidTreeView.

  • Su árbol de nivel N.

  • estilo personalizado para los nodos

  • guardar el estado después de la rotación

AndroidTreeView

+0

Gracias es útil, ¿Puedo agregar un nivel con iconos horizontales, – Anup

+1

¿Se puede modificar dinámicamente la vista? Específicamente, si inicialmente creo un árbol que contiene un nodo de punto final (hoja), ¿puedo luego cambiarlo a una carpeta? – FractalBob

3

He encontrado una solución más fácil a este problema, como yo soy algo intermedio en mis habilidades de codificación En mi situación, necesitaba una Windows-themed Tree View, que después de una lluvia de ideas, ¡pude implementar sin casi ninguna codificación!

Aquí está el truco: utilizar un WebView y una página HTML incrustado para mostrar una costumbre de vista de árbol, y el uso de súper práctico interfaz de comunicación JavaScript de Android para recibir selecciones & clicks: Proof of Concept Example on Android-er Blog

Con este poder podemos tomar ventaja de una gran colección de fragmentos de control JS/CSS en la web. Themeable Windows7-Style jQuery TreeView control -- jsTree

¡Muchas posibilidades y potencia con Android por ahí, feliz codificación!