Как добавить разделители/разделители разделов в ListView?

В настоящее время я создаю меню для своего приложения, используя подкласс DrawerLayout и ArrayAdapter, чтобы добиться чего-то похожего на меню ящика Facebook.

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

Код моего текущего подкласса ArrayAdaptor выглядит следующим образом:

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;
    }
}

Я предполагаю, что мне нужно переопределить функцию, которая заполняет ListView, вызвав функцию getView, но я не могу найти, что это за функция.


person Jivay    schedule 18.08.2013    source источник


Ответы (2)


Если вам нужны простые разделы в ListView, ознакомьтесь с этим руководством:

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

или этот учебник:

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

Второй вариант не такой подробный, но, вероятно, его легче понять/сделать проще.

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

Из учебника:

ListViews и, в частности, адаптеры могут обрабатывать несколько типов представлений. Если вы посмотрите на интерфейс адаптера, вы заметите, что он содержит два конкретных метода:

  • getViewTypeCount(), который возвращает количество типов представлений, которыми управляет ваш адаптер. В большинстве случаев этот метод возвращает 1, поскольку все элементы ListView похожи. В этом случае, возвращая 2, ListView будет обрабатывать два типа представлений: обычные представления элементов и представления разделителя.
  • getItemViewType(int) должен возвращать целое число между 0 (включительно) и getViewTypeCount() (не включая). Данное число выражает тип представления в данной позиции. Например, мы можем гарантировать, что возвращаемые значения равны 0 для обычных представлений элементов и 1 для разделителей.
person Philipp Jahoda    schedule 18.08.2013
comment
Нет, это может быть полезно, но это не то, что я ищу. СВЯЗАННЫЕ С ФОТО Вот такое меню я пытаюсь сделать, с такого рода разделителями между Вашими страницами и разделом, в котором находится Справочный центр. - person Jivay; 19.08.2013
comment
Тогда я, должно быть, неправильно понял. Не могли бы вы объяснить более конкретно? Что вы ищете? - person Philipp Jahoda; 19.08.2013
comment
отредактировал, нажал Enter, не закончив. Я хотел бы поместить определенный разделитель между определенными разделами моего ListView и поместить заголовок в этот разделитель. - person Jivay; 19.08.2013
comment
Вторая ссылка проще, она мне помогла. - person CoolMind; 01.09.2016

Я добавляю ответ здесь, так как я нашел другой способ сделать это. Это немного похоже на ссылки, опубликованные @Phil.

Сначала я установил массив строк меню, которое хочу отобразить. Я написал этот массив в файле ресурсов XML для личного удобства.

<?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>

Обратите внимание, что у меня есть два элемента, использующих префикс -sep-. Это будут наши разделители.

Затем идет DrawerMenuAdapter, который я показал ранее, который все еще является ArrayAdapter, к которому я добавил некоторые функции:

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;
    }
}

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

Суть здесь в том, как код ищет разделители, строки с префиксом -sep-. Как только он найден, префикс удаляется, а соответствующий макет присваивается разделителю.

Хорошо, это то, что я нашел. После этого вам нужно будет найти собственный способ добавления прослушивателей кликов. Мины реализованы в DrawerLayout.setOnCliclListener, который в основном выполняет работу точно так же, как говорится в документации Google. Но вы также можете использовать setOnclickListener в своем представлении по мере их добавления и использовать файл XML, в котором вы можете установить свои собственные атрибуты onClick...

Надеюсь поможет =)

person Jivay    schedule 19.08.2013