Pregunta ¿Cómo agregar divisores / divisores de sección a un ListView?


Actualmente estoy creando un menú para mi aplicación, usando una subclase DrawerLayout y una ArrayAdapter para lograr algo parecido al menú del cajón de Facebook.

Actualmente no tengo problemas para crear la lista, pero ahora que se ve bien, me gustaría agregar separadores entre diferentes tipos de opciones (es decir, opciones relacionadas con el usuario y relacionadas con la aplicación) y una barra de búsqueda en la parte superior del menú.

El código de mi subclase ArrayAdaptor actual es el siguiente:

public class DrawerMenuAdapter extends ArrayAdapter<String>{
    private Context context;
    private String[] values;
    private int resId;

    public DrawerMenuAdapter(Context context, int textViewResourceId, String[] values) {
        super(context, textViewResourceId, values);
        this.context = context;
        this.values = values;
        this.resId = textViewResourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(this.resId, parent, false);

        TextView elementText = (TextView)rowView.findViewById(R.id.element_text);
        ImageView elementImage = (ImageView)rowView.findViewById(R.id.element_icon);
        String textValue = values[position];

        elementText.setText(textValue);

        //This switch adds the icons to the related elements
        switch (position){
            case 0:
                elementImage.setImageResource(R.drawable.search);
                break;
            case 1:
                elementImage.setImageResource(R.drawable.facebook_friends);
                break;
            case 2:
                elementImage.setImageResource(R.drawable.flirts_history);
                break;
            case 3:
                elementImage.setImageResource(R.drawable.premium);
                break;
            case 4:
                elementImage.setImageResource(R.drawable.settings);
                break;
            case 5:
                elementImage.setImageResource(R.drawable.share_app);
                break;
            case 6:
                elementImage.setImageResource(R.drawable.cgu);
                break;
        }


        return rowView;
    }
}

Supongo que tengo que anular la función que rellena el ListView llamando a la función getView, pero no puedo encontrar la función que es.


32
2017-08-18 18:42


origen


Respuestas:


Si quieres simple secciones en su ListView, mira este tutorial:

http://cyrilmottier.com/2011/07/05/listview-tips-tricks-2-section-your-listview/

o este tutorial:

http://bartinger.at/listview-with-sectionsseparators/

El segundo no es tan detallado, pero probablemente más fácil de entender / simplificado.

La idea básica es que haga que su ListAdapter tenga diferentes tipos de vistas. Por ejemplo, dos vistas diferentes donde un tipo es el elemento de la lista real que muestra la información, y el otro tipo de vista es el divisor de la sección.

Del tutorial:

ListViews y más específicamente Los adaptadores pueden manejar varios tipos de Vistas. Si echas un vistazo a la interfaz del adaptador, verás que contiene dos métodos específicos:

  • getViewTypeCount() que devuelve la cantidad de tipos de Vistas que AdapterView administra. La mayoría de las veces este método devuelve 1 porque todos los elementos de ListView son similares. En este caso, al devolver 2, el ListView manejará dos tipos de Vistas: el elemento regular Vistas y las vistas separadoras
  • getItemViewType(int) debe devolver un número entero Entre 0 (inclusive) y getViewTypeCount() (exclusivo). El número dado expresa el tipo de la Vista en la posición dada. Por ejemplo, podemos asegurarnos los valores devueltos son 0 para las vistas de elementos regulares y 1 para el separadores

37
2017-08-18 18:47



Estoy agregando una respuesta aquí, ya que he pensado de otra manera para esto. Se parece un poco a los enlaces @Phil publicados.

Primero configuro una matriz de cadenas del menú que quiero mostrar. He escrito esta matriz en un archivo de recursos XML para su conveniencia personal.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array
            name="drawer_menu_options">
        <item>Username</item>
        <item>-sep-Flirter</item>
        <item>Recherche</item>
        <item>Amis Facebook</item>
        <item>Flirts</item>
        <item>Compte premium</item>
        <item>-sep-Menu</item>
        <item>Réglages</item>
        <item>Inviter des amis</item>
        <item>CGU</item>
    </string-array>
</resources>

Tenga en cuenta que tengo dos elementos usando el prefijo -sep-. Estos serán nuestros separadores.

Luego viene el DrawerMenuAdapter que he mostrado anteriormente, que sigue siendo un ArrayAdapter, en el que he agregado algunas funcionalidades:

public class DrawerMenuAdapter extends ArrayAdapter<String>{
    private Context context;
    private String[] values;
    private int resId;
    private int separatorId = 0;
    private int userbarId = 0;

    public DrawerMenuAdapter(Context context, int textViewResourceId, String[] values) {
        super(context, textViewResourceId, values);
        this.context = context;
        this.values = values;
        this.resId = textViewResourceId;
    }

    public void setSeparator(int resId){
        separatorId = resId;
    }

    public void setUserbarId(int resId){
        userbarId = resId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        View rowView;

        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if(userbarId != 0 && values[position].equals("Username")){
            rowView = inflater.inflate(this.userbarId, parent, false);

        }else if(separatorId != 0 && values[position].startsWith("-sep-")){
            rowView = inflater.inflate(this.separatorId, parent, false);

        }else{
            rowView = inflater.inflate(this.resId, parent, false);
        }

        TextView elementText = (TextView)rowView.findViewById(R.id.element_text);
        String textValue = values[position];

        /* If the current line is a separator, just display a separator. Otherwise, set the
        matching picture
         */
        if(textValue.startsWith("-sep-")){
            elementText.setText(textValue.substring("-sep-".length()));

        }else{
            if(textValue.equals("Username")){
                elementText.setText(context.getSharedPreferences("LovRUserSettings", 0)
                        .getString("firstName", "Username"));
            }else{
                elementText.setText(textValue);
            }
            ImageView elementImage = (ImageView)rowView.findViewById(R.id.element_icon);
            switch (position){
                case 2:
                    elementImage.setImageResource(R.drawable.search);
                    break;
                case 3:
                    elementImage.setImageResource(R.drawable.facebook_friends);
                    break;
                case 4:
                    elementImage.setImageResource(R.drawable.flirts_history);
                    break;
                case 5:
                    elementImage.setImageResource(R.drawable.premium);
                    break;
                case 7:
                    elementImage.setImageResource(R.drawable.settings);
                    break;
                case 8:
                    elementImage.setImageResource(R.drawable.share_app);
                    break;
                case 9:
                    elementImage.setImageResource(R.drawable.cgu);
                    break;
            }
        }


        return rowView;
    }
}

En este código, hay un objeto llamado userBar. No es necesario que preste atención a esto, pero si está interesado, es otro elemento de menú, utilizando un archivo de diseño específico en lugar del que uso para los elementos de menú regulares. Es una manera de demostrar que puede agregar cualquier tipo de diseño específico en cualquier lugar que desee, simplemente leyendo sus cadenas.

El punto principal aquí es en la forma en que el código busca separadores, las cadenas con el -sep-prefijo. Una vez que se encuentra uno, se elimina el prefijo y el diseño correspondiente se atribuye al separador.

Aight, eso es lo que he encontrado. Después de esto, tendrá que encontrar su propia forma de agregar escuchas de clic. Las minas se implementan en DrawerLayout.setOnCliclListener que básicamente hace el trabajo exactamente de la misma manera que dice la documentación de Google. Pero también puedes usar setOnclickListenera su vista a medida que los agrega, y utiliza un archivo XML donde puede establecer su propio onClick atributos ...

Espero que ayude =)


7
2017-08-19 21:36