Android ListView 헤더


122

일종의 이벤트가있는 ListView가 있습니다. 이벤트는 날짜별로 정렬되어 있으며 매일 날짜가있는 헤더를 갖고 싶습니다. 그러면 이벤트가 아래에서 수신됩니다.

이 목록을 채우는 방법은 다음과 같습니다.

ArrayList<TwoText> crs = new ArrayList<TwoText>();

crs.add(new TwoText("This will be header", event.getDate()));

for (Event event : events) {
    crs.add(new TwoText(event.getStartString() + "-" + event.getEndString(), event.getSubject()));
}

arrayAdapter = new TwoTextArrayAdapter(this, R.layout.my_list_item, crs);
lv1.setAdapter(arrayAdapter);

그리고 이것이 내 클래스 TwoText의 모습입니다.

public class TwoText {
    public String classID;
    public String state;

    public TwoText(String classID, String state) {
        this.classID = classID;
        this.state = state;
    }
}

그리고 이것이 내 TwoTextArrayAdapter 클래스의 모습입니다.

import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class TwoTextArrayAdapter extends ArrayAdapter<TwoText> {

    private ArrayList<TwoText> classes;
    private Activity con;
    TextView seperator;

    public TwoTextArrayAdapter(Activity context, int textViewResourceId, ArrayList<TwoText> classes) {
        super(context, textViewResourceId, classes);
        this.con = context;
        this.classes = classes;

    }

    @Override

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

        View v = convertView;

        if (v == null) {

            LayoutInflater vi = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            v = vi.inflate(R.layout.my_list_item, null);

        }

        TwoText user = classes.get(position);

        if (user != null) {

            TextView content1 = (TextView) v.findViewById(R.id.list_content1);

            TextView content2 = (TextView) v.findViewById(R.id.list_content2);

            if (content1 != null) {

                content1.setText(user.classID);
            }   
            if(content2 != null) {

                content2.setText(user.state);
            }
        }
        return v;
    }
}

그리고 이것은 my_list_item.xml입니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/list_content1"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="5dip"
            android:clickable="false"
            android:gravity="center"
            android:longClickable="false"
            android:paddingBottom="1dip"
            android:paddingTop="1dip"
            android:text="sample"
            android:textColor="#ff7f1d"
            android:textSize="17dip"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/list_content2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="5dip"
            android:clickable="false"
            android:gravity="center"
            android:linksClickable="false"
            android:longClickable="false"
            android:paddingBottom="1dip"
            android:paddingTop="1dip"
            android:text="sample"
            android:textColor="#6d6d6d"
            android:textSize="17dip" />
    </LinearLayout>

</LinearLayout>

지금 내가하는 일은 일반 목록 객체와 마찬가지로 헤더를 추가하고 있지만 헤더로 사용하고 제 경우에는 날짜가 있기를 바랍니다.

헤더에 대한 내 XML 에이 코드가 있습니다.

<TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

그리고 필요하지 않을 때는 숨기고 필요할 때 보여 주려고했지만 나머지 코드를 엉망으로 만들었습니다. 튜토리얼을 몇 번 더 시도했지만 효과도 동일했습니다.

누구든지 그렇게 쉬운 방법을 안내해 줄 수 있습니까?

답변:


334

방법은 다음과 같습니다. 키는 클래스의 getItemViewTypegetViewTypeCount 입니다 Adapter. getViewTypeCount목록에있는 항목의 유형을 반환합니다.이 경우에는 헤더 항목과 이벤트 항목이 있으므로 두 개입니다. getItemViewType어떤 종류의 반환해야 View우리가 입력에 있습니다 position.

안드로이드는 당신에게 올바른 유형을 통과 처리됩니다 ViewconvertView자동으로.

아래 코드의 결과는 다음과 같습니다.

먼저 두 개의 목록 항목 유형이 구현할 인터페이스가 있습니다.

public interface Item {
    public int getViewType();
    public View getView(LayoutInflater inflater, View convertView);
}

그런 다음 목록을 가져 오는 어댑터가 있습니다. Item

public class TwoTextArrayAdapter extends ArrayAdapter<Item> {
    private LayoutInflater mInflater;

    public enum RowType {
        LIST_ITEM, HEADER_ITEM
    }

    public TwoTextArrayAdapter(Context context, List<Item> items) {
        super(context, 0, items);
        mInflater = LayoutInflater.from(context);
    }

    @Override
    public int getViewTypeCount() {
        return RowType.values().length;

    }

    @Override
    public int getItemViewType(int position) {
        return getItem(position).getViewType();
    }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
   return getItem(position).getView(mInflater, convertView);
}

EDIT Better For Performance .. 스크롤 할 때 알아 차릴 수 있습니다.

private static final int TYPE_ITEM = 0; 
private static final int TYPE_SEPARATOR = 1; 

public View getView(int position, View convertView, ViewGroup parent)  {
    ViewHolder holder = null;
    int rowType = getItemViewType(position);
    View View;
    if (convertView == null) {
        holder = new ViewHolder();
        switch (rowType) {
            case TYPE_ITEM:
                convertView = mInflater.inflate(R.layout.task_details_row, null);
                holder.View=getItem(position).getView(mInflater, convertView);
                break;
            case TYPE_SEPARATOR:
                convertView = mInflater.inflate(R.layout.task_detail_header, null);
                holder.View=getItem(position).getView(mInflater, convertView);
                break;
        }
        convertView.setTag(holder);
    }
    else
    {
        holder = (ViewHolder) convertView.getTag();
    }
    return convertView; 
} 

public static class ViewHolder {
    public  View View; } 
}

그런 다음 구현 클래스가 Item있고 올바른 레이아웃을 팽창시킵니다. 귀하의 경우에는 Header수업과 수업과 같은 것이 ListItem있습니다.

   public class Header implements Item {
    private final String         name;

    public Header(String name) {
        this.name = name;
    }

    @Override
    public int getViewType() {
        return RowType.HEADER_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View view;
        if (convertView == null) {
            view = (View) inflater.inflate(R.layout.header, null);
            // Do some initialization
        } else {
            view = convertView;
        }

        TextView text = (TextView) view.findViewById(R.id.separator);
        text.setText(name);

        return view;
    }

}

그리고 ListItem수업

    public class ListItem implements Item {
    private final String         str1;
    private final String         str2;

    public ListItem(String text1, String text2) {
        this.str1 = text1;
        this.str2 = text2;
    }

    @Override
    public int getViewType() {
        return RowType.LIST_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View view;
        if (convertView == null) {
            view = (View) inflater.inflate(R.layout.my_list_item, null);
            // Do some initialization
        } else {
            view = convertView;
        }

        TextView text1 = (TextView) view.findViewById(R.id.list_content1);
        TextView text2 = (TextView) view.findViewById(R.id.list_content2);
        text1.setText(str1);
        text2.setText(str2);

        return view;
    }

}

그리고 Activity그것을 표시 하는 간단한

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        List<Item> items = new ArrayList<Item>();
        items.add(new Header("Header 1"));
        items.add(new ListItem("Text 1", "Rabble rabble"));
        items.add(new ListItem("Text 2", "Rabble rabble"));
        items.add(new ListItem("Text 3", "Rabble rabble"));
        items.add(new ListItem("Text 4", "Rabble rabble"));
        items.add(new Header("Header 2"));
        items.add(new ListItem("Text 5", "Rabble rabble"));
        items.add(new ListItem("Text 6", "Rabble rabble"));
        items.add(new ListItem("Text 7", "Rabble rabble"));
        items.add(new ListItem("Text 8", "Rabble rabble"));

        TwoTextArrayAdapter adapter = new TwoTextArrayAdapter(this, items);
        setListAdapter(adapter);
    }

}

레이아웃 R.layout.header

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

    <TextView
        style="?android:attr/listSeparatorTextViewStyle"
        android:id="@+id/separator"
        android:text="Header"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#757678"
        android:textColor="#f5c227" />

</LinearLayout>

레이아웃 R.layout.my_list_item

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

    <TextView
        android:id="@+id/list_content1"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dip"
        android:clickable="false"
        android:gravity="center"
        android:longClickable="false"
        android:paddingBottom="1dip"
        android:paddingTop="1dip"
        android:text="sample"
        android:textColor="#ff7f1d"
        android:textSize="17dip"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/list_content2"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_margin="5dip"
        android:clickable="false"
        android:gravity="center"
        android:linksClickable="false"
        android:longClickable="false"
        android:paddingBottom="1dip"
        android:paddingTop="1dip"
        android:text="sample"
        android:textColor="#6d6d6d"
        android:textSize="17dip" />

</LinearLayout>

레이아웃 R.layout.activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</RelativeLayout>

또한 더 멋지게 사용하고 ViewHolders, 비동기식으로로드하거나 원하는대로 사용할 수 있습니다 .


5
여기에서 솔루션이 마음에 들었지만 ArrayAdapter를 확장하므로 자신의 항목 목록을 추적해서는 안됩니다. ArrayAdapter에서 내부적으로 추적 된 것을 사용하십시오. 그렇지 않으면 당신은 당신의 항목을 저장하는 메모리의 양을 두 배로 있습니다
제이 Soyer

3
탁월한 솔루션. 헤더를 클릭 할 수없는 경우 (생성자에서 설정할 수 있음) 어댑터에만 추가합니다. @Override public boolean isEnabled (int position) {return (getItem (position) .getViewType () == RowType.LIST_ITEM .ordinal ()); }
dwbrito

2
목록보기가 스크롤 될 때 행이 무작위 화됩니까? 사람이 안내하시기 바랍니다 수
i_raqz

1
왜 구글은 단지 3 줄의 코드만으로 이것을 할 수 없습니까?
Ojonugwa Jude Ochalifu 2015-06-22

4
이 답변은 내가 찾은 최고의 답변 중 하나입니다. 명확하고 간결하며 잘 설명되어 있습니다. 그러나 ListView의 결과가 반 무작위 순서 (첫 번째 헤더와 항목은 괜찮 았고 다음은 엉망이 됨)에 문제가 있었으므로 문제가 무엇인지 알아낼 수있었습니다. 'Edit Better For Performance .. 아래의 코드 블록은 나를 위해 그것을 엉망으로 만들었습니다. Custom ArrayAdapter 클래스에서 이것을 제거하면 문제가 해결되었습니다. 나는 무작위 결과를 얻는 모든 사람들에게 이것을 시도하도록 조언합니다. 그래도 훌륭한 답변에 감사드립니다. 정말 나를 도왔습니다!
blueprintchris

9

항목 (자식)을 구분하는 헤더 (그룹)가 있는 ExpandableListView 를 찾고있을 것입니다 .

주제에 대한 멋진 튜토리얼 : 여기 .


나는 그들이 확장 될 싶지 않다
Rohit Malish에게

이것이 유일한 문제인 경우 onItemClick 메서드를 재정 의하여 뷰 확장 / 축소를 방지 할 수 있습니다.
Saito Mea 2011

하지만 난 여전히 다른 목적을 위해 클릭 할 수 그들을 필요
Rohit Malish

Err ... 실제로는 onGroupClick"헤더"클릭 만 처리하고 클릭이나 이와 같은 것을 비활성화 할 필요가 없습니다. 축소 작업을 취소하고 모든 그룹을 처음부터 확장되도록 설정하기 만하면됩니다.
Saito Mea 2011

ExpandableListView대부분의 경우 이것이 최선 이라는 데 동의합니다 . 그러나 때때로 플랫 목록을 표시하고 다른 시간에는 내 활동에서 헤더가있는 목록을 표시하고 싶은 상황이 있습니다. 슬프게도 ExpandableListAdapter인터페이스는 인터페이스를 확장하지 않으므로 ListAdapter다형성을 위해 @antew의 솔루션을 사용해야합니다.
tytk

3

대안 으로이 사용 사례를 위해 설계된 멋진 타사 라이브러리가 있습니다. 어댑터에 저장되는 데이터를 기반으로 헤더를 생성해야합니다. Rolodex 어댑터라고하며 ExpandableListViews. 헤더가있는 일반 목록처럼 작동하도록 쉽게 사용자 정의 할 수 있습니다.

OP의 Event객체를 사용하고 헤더가 그 Date와 관련된 것을 기반으로한다는 것을 알면 코드는 다음과 같습니다.

활동

    //There's no need to pre-compute what the headers are. Just pass in your List of objects. 
    EventDateAdapter adapter = new EventDateAdapter(this, mEvents);
    mExpandableListView.setAdapter(adapter);

어댑터

private class EventDateAdapter extends NFRolodexArrayAdapter<Date, Event> {

    public EventDateAdapter(Context activity, Collection<Event> items) {
        super(activity, items);
    }

    @Override
    public Date createGroupFor(Event childItem) {
        //This is how the adapter determines what the headers are and what child items belong to it
        return (Date) childItem.getDate().clone();
    }

    @Override
    public View getChildView(LayoutInflater inflater, int groupPosition, int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {
        //Inflate your view

        //Gets the Event data for this view
        Event event = getChild(groupPosition, childPosition);

        //Fill view with event data
    }

    @Override
    public View getGroupView(LayoutInflater inflater, int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        //Inflate your header view

        //Gets the Date for this view
        Date date = getGroup(groupPosition);

        //Fill view with date data
    }

    @Override
    public boolean hasAutoExpandingGroups() {
        //This forces our group views (headers) to always render expanded.
        //Even attempting to programmatically collapse a group will not work.
        return true;
    }

    @Override
    public boolean isGroupSelectable(int groupPosition) {
        //This prevents a user from seeing any touch feedback when a group (header) is clicked.
        return false;
    }
}

1

날짜 (예 : 2016 년 12 월 1 일)를 헤더로 만들기 위해 수행 한 작업입니다. StickyHeaderListView 라이브러리를 사용했습니다.

https://github.com/emilsjolander/StickyListHeaders

날짜를 밀리 초 단위의 long으로 변환하고 [시간을 포함하지 않음] 헤더 ID로 만듭니다.

@Override
public long getHeaderId(int position) {
    return <date in millis>;
}

1

다음은 antew의 상세하고 유용한 답변을 기반으로 한 샘플 프로젝트로 , ListView스크롤 성능을 향상시키기 위해 뷰 홀더를 통합하는 다중 헤더를 구현합니다 .

이 프로젝트에서에 표시된 객체는 ListView클래스 HeaderItem또는 클래스의 인스턴스이며 RowItem둘 다 추상 클래스의 하위 클래스 Item입니다. 의 각 하위 클래스 Item는 사용자 정의 어댑터의 다른보기 유형에 해당합니다 ItemAdapter. 의 메서드 는 어댑터 의 메서드에 전달 된 위치에서 사용되는 하위 클래스 에 따라 또는 의 개별화 된 메서드에 각 목록 항목에 대한 뷰 생성 getView()ItemAdapter위임합니다 . 각 서브 클래스는 자체 뷰 홀더를 제공합니다.getView()HeaderItemRowItemItemgetView()Item

뷰 홀더는 다음과 같이 구현됩니다. getView()온 방법 Item서브 클래스가 있는지 여부를 확인 View받는 전달 된 객체 getView()에 대한 방법은 ItemAdapter널이다. 그렇다면 적절한 레이아웃이 확장되고 뷰 홀더 객체가 인스턴스화되고를 통해 확장 된 뷰와 연결됩니다 View.setTag(). 경우 View객체가 null는 아니고, 다음 뷰 홀더 객체는 이미 뷰와 연관되고, 뷰 홀더를 통해 검색됩니다 View.getTag(). 뷰 홀더가 사용되는 방식은의 다음 코드 스 니펫에서 확인할 수 있습니다 HeaderItem.

@Override
View getView(LayoutInflater i, View v) {
    ViewHolder h;
    if (v == null) {
        v = i.inflate(R.layout.header, null);
        h = new ViewHolder(v);
        v.setTag(h);
    } else {
        h = (ViewHolder) v.getTag();
    }
    h.category.setText(text());
    return v;
}

private class ViewHolder {
    final TextView category;

    ViewHolder(View v) {
        category = v.findViewById(R.id.category);
    }
}

ListView의 전체 구현은 다음과 같습니다. 다음은 Java 코드입니다.

import android.app.ListActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class MainActivity extends ListActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new ItemAdapter(getItems()));
    }

    class ItemAdapter extends ArrayAdapter<Item> {
        final private List<Class<?>> viewTypes;

        ItemAdapter(List<Item> items) {
            super(MainActivity.this, 0, items);
            if (items.contains(null))
                throw new IllegalArgumentException("null item");
            viewTypes = getViewTypes(items);
        }

        private List<Class<?>> getViewTypes(List<Item> items) {
            Set<Class<?>> set = new HashSet<>();
            for (Item i : items) 
                set.add(i.getClass());
            List<Class<?>> list = new ArrayList<>(set);
            return Collections.unmodifiableList(list);
        }

        @Override
        public int getViewTypeCount() {
            return viewTypes.size();
        }

        @Override
        public int getItemViewType(int position) {
            Item t = getItem(position);
            return viewTypes.indexOf(t.getClass());
        }

        @Override
        public View getView(int position, View v, ViewGroup unused) {
            return getItem(position).getView(getLayoutInflater(), v);
        }
    }

    abstract private class Item {
        final private String text;

        Item(String text) {
            this.text = text;
        }

        String text() { return text; }

        abstract View getView(LayoutInflater i, View v);
    }

    private class HeaderItem extends Item {
        HeaderItem(String text) {
            super(text);
        }

        @Override
        View getView(LayoutInflater i, View v) {
            ViewHolder h;
            if (v == null) {
                v = i.inflate(R.layout.header, null);
                h = new ViewHolder(v);
                v.setTag(h);
            } else {
                h = (ViewHolder) v.getTag();
            }
            h.category.setText(text());
            return v;
        }

        private class ViewHolder {
            final TextView category;

            ViewHolder(View v) {
                category = v.findViewById(R.id.category);
            }
        }
    }

    private class RowItem extends Item {
        RowItem(String text) {
            super(text);
        }

        @Override
        View getView(LayoutInflater i, View v) {
            ViewHolder h;
            if (v == null) {
                v = i.inflate(R.layout.row, null);
                h = new ViewHolder(v);
                v.setTag(h);
            } else {
                h = (ViewHolder) v.getTag();
            }
            h.option.setText(text());
            return v;
        }

        private class ViewHolder {
            final TextView option;

            ViewHolder(View v) {
                option = v.findViewById(R.id.option);
            }
        }
    }

    private List<Item> getItems() {
        List<Item> t = new ArrayList<>();
        t.add(new HeaderItem("Header 1"));
        t.add(new RowItem("Row 2"));
        t.add(new HeaderItem("Header 3"));
        t.add(new RowItem("Row 4"));

        t.add(new HeaderItem("Header 5"));
        t.add(new RowItem("Row 6"));
        t.add(new HeaderItem("Header 7"));
        t.add(new RowItem("Row 8"));

        t.add(new HeaderItem("Header 9"));
        t.add(new RowItem("Row 10"));
        t.add(new HeaderItem("Header 11"));
        t.add(new RowItem("Row 12"));

        t.add(new HeaderItem("Header 13"));
        t.add(new RowItem("Row 14"));
        t.add(new HeaderItem("Header 15"));
        t.add(new RowItem("Row 16"));

        t.add(new HeaderItem("Header 17"));
        t.add(new RowItem("Row 18"));
        t.add(new HeaderItem("Header 19"));
        t.add(new RowItem("Row 20"));

        t.add(new HeaderItem("Header 21"));
        t.add(new RowItem("Row 22"));
        t.add(new HeaderItem("Header 23"));
        t.add(new RowItem("Row 24"));

        t.add(new HeaderItem("Header 25"));
        t.add(new RowItem("Row 26"));
        t.add(new HeaderItem("Header 27"));
        t.add(new RowItem("Row 28"));
        t.add(new RowItem("Row 29"));
        t.add(new RowItem("Row 30"));

        t.add(new HeaderItem("Header 31"));
        t.add(new RowItem("Row 32"));
        t.add(new HeaderItem("Header 33"));
        t.add(new RowItem("Row 34"));
        t.add(new RowItem("Row 35"));
        t.add(new RowItem("Row 36"));

        return t;
    }

}

또한 각 Item 하위 클래스에 대해 하나씩 두 개의 목록 항목 레이아웃이 있습니다. 다음은 headerHeaderItem에서 사용 하는 레이아웃입니다 .

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#FFAAAAAA"
    >
    <TextView
        android:id="@+id/category"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:textColor="#FF000000"
        android:textSize="20sp"
        android:textStyle="bold"
        />
 </LinearLayout>

다음은 rowRowItem에서 사용 하는 레이아웃입니다 .

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    >
    <TextView
        android:id="@+id/option"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="15sp"
        />
</LinearLayout>

다음은 결과 ListView의 일부 이미지입니다.

여러 헤더가있는 ListView

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.