Как добавить несколько заголовков в одном ListView с помощью addHeaderView ()? - PullRequest
13 голосов
/ 17 сентября 2010

Может ли Android addHeaderView () использоваться для добавления нескольких заголовков в один ListView? Может кто-нибудь привести пример, как это сделать?

Я смог выполнить то, что хотел, манипулируя классом IconicAdapter ... есть ли причина, почему я не должен делать это таким образом? Я чувствую, что это может быть изменено для более продвинутых реализаций. В моем случае я знаю, что у меня будет два раздела с заголовком + 2 строки в каждом разделе.

class IconicAdapter extends ArrayAdapter<String> {
    IconicAdapter() {
        super(ContactTabProfileResource.this, R.layout.row_iconic, mArrayList);
    }


    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = getLayoutInflater();
        View row = null;

        if(position == 1 || position == 5) { // phone 
            row = inflater.inflate(R.layout.row_iconic, parent, false);
            TextView label =(TextView)row.findViewById(R.id.label);
            label.setText(mArrayList.get(position));
            ImageView icon = (ImageView)row.findViewById(R.id.rowicon);
            icon.setImageResource(R.drawable.icon_phone);
        } else if (position == 2 || position == 6) { // email
            row = inflater.inflate(R.layout.row_iconic, parent, false);
            TextView label =(TextView)row.findViewById(R.id.label);
            label.setText(mArrayList.get(position));
            ImageView icon = (ImageView)row.findViewById(R.id.rowicon);
            icon.setImageResource(R.drawable.icon_email);
        } else if (position == 0 || position == 4) { // section header
            row = inflater.inflate(R.layout.row_header, parent, false);
            TextView label =(TextView)row.findViewById(R.id.label);
            label.setText(mArrayList.get(position));
            label.setBackgroundColor(Color.GRAY);   
        } else if (position == 3) { // section divider
            row = inflater.inflate(R.layout.row_header, parent, false);
            TextView label =(TextView)row.findViewById(R.id.label);
            label.setText(" ");
        }

        return(row);

    }
}

Затем я создал два разных макета XML. row_header.xml - для строк заголовка, а row_iconic.xml - для строк без заголовка, которые содержат значок.

row_header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:gravity="right"
>    

  <TextView
    android:id="@+id/label"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:paddingRight="10dp"
    android:paddingLeft="10px"
    android:gravity="left"
    android:textStyle="bold"
    />    
</LinearLayout>

row_iconic.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  android:gravity="right"
>    

  <TextView
    android:id="@+id/label"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="16sp"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:paddingRight="10dp"
    android:paddingLeft="44px"
    />  
    <ImageView
    android:id="@+id/rowicon"
    android:layout_width="40dp"
    android:paddingRight="10dp"
    android:paddingTop="10dp"
    android:layout_height="30dp"        
    android:src="@drawable/icon"
    />    
</LinearLayout>

Ответы [ 4 ]

13 голосов
/ 21 сентября 2010

То, что вы хотите, разработчики Android могут называть разделителем или подзаголовком списка («верхние и нижние колонтитулы» располагаются только вверху или внизу списка). Суть того, как вы можете это сделать, заключается в использовании ListAdapter, который оборачивает другие ListAdapter и достаточно умен, чтобы возвращать тип представления заголовка для определенных строк и отслеживать смещения, или оборачивает эти представления разделителя в свои собственные мини-адаптеры.

Взгляните на SectionedListAdapter Марка Мерфи , GPL, который использует первый подход (на основе кода Джеффа Шарки), или его MergeAdapter , и посмотрите этот SO вопрос .

Это очень далеко от изящной обработки подзаголовков умных списков на iPhone, но использовать MergeAdapter довольно просто и очень гибко, когда вы точно понимаете, что происходит внутри адаптеров.

7 голосов
/ 22 сентября 2010

Если вы хотите вернуть разные макеты (например, элементы и заголовки), вы должны использовать getItemViewType(int position).Итак, код вашего адаптера должен выглядеть следующим образом:

private static final int TYPE_HEADER = 0;
private static final int TYPE_ICONIC = 1;

@Override
public int getViewTypeCount() {
    return 2;   // we have two types, so just return 2
}

@Override
public int getItemViewType(int position) {
    // TODO: return TYPE_HEADER here if this position is a header, otherwise return TYPE_ICONIC
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO: return the appropriate layout
    // hint: you might call getItemViewType(position) yourself here to know of which type the layout is
}

Вот как это работает.Чтобы убедиться, что заголовки не могут быть выбраны, вы можете выбросить ArrayAdapter и использовать вместо него ListAdapter, переопределяя isEnabled(int position), чтобы вернуть false для ваших представлений заголовка.; -)

1 голос
/ 17 сентября 2010

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

0 голосов
/ 25 сентября 2010

Вы также можете использовать этот класс в качестве примера.Он поддерживает «разделы» и «действия», где «разделы» - это просто группы «действий» (элементов), у них есть не кликаемый и не выбираемый элемент - заголовок.«Действия» могут указывать обработчик onClick, который будет вызываться при нажатии этого «действия», если оно существует.Он также содержит ImageLoader для извлечения изображений для «действий» из Интернета.

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