ส่วนหัวของ 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>

สิ่งที่ฉันทำในขณะนี้คือฉันกำลังเพิ่มส่วนหัวเช่นเดียวกับรายการวัตถุทั่วไป แต่ Id ชอบให้เป็นส่วนหัวและในกรณีของฉันมีวันที่อยู่

ฉันมีรหัสนี้ใน 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

นี่คือวิธีที่ฉันทำคีย์คือgetItemViewTypeและgetViewTypeCountในAdapterคลาส getViewTypeCountส่งคืนจำนวนประเภทของรายการที่เรามีในรายการในกรณีนี้เรามีรายการส่วนหัวและรายการเหตุการณ์ดังนั้นสองรายการ getItemViewTypeควรกลับสิ่งที่ประเภทของเรามีในการป้อนข้อมูลViewposition

Android แล้วจะดูแลคุณผ่านประเภทสิทธิของViewในconvertViewโดยอัตโนมัติ

ผลลัพธ์ของโค้ดด้านล่างจะเป็นอย่างไร:

อันดับแรกเรามีอินเทอร์เฟซที่จะใช้รายการสองประเภทของเรา

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 มิฉะนั้นคุณจะเพิ่มหน่วยความจำเป็นสองเท่าในการจัดเก็บรายการของคุณ
Jay Soyer

3
ทางออกที่ยอดเยี่ยม ฉันจะเพิ่มสิ่งนี้ลงในอะแด็ปเตอร์เท่านั้นหากส่วนหัวไม่สามารถคลิกได้ (ซึ่งสามารถตั้งค่าได้ในตัวสร้าง) @Override บูลีนสาธารณะ isEnabled (ตำแหน่ง int) {return (getItem (position) .getViewType () == RowType.LIST_ITEM .ordinal ()); }
dwbrito

2
แถวจะสุ่มเมื่อมีการเลื่อนมุมมองรายการ? ใครช่วยแนะนำ
i_raqz

1
เหตุใด Google จึงไม่สามารถทำให้สิ่งนี้เกิดขึ้นได้ด้วยโค้ดเพียง 3 บรรทัด?
Ojonugwa Jude Ochalifu

4
คำตอบนี้เป็นหนึ่งในคำตอบที่ดีที่สุดที่ฉันพบใน SO - ชัดเจนกระชับและอธิบายได้ดี อย่างไรก็ตามฉันมีปัญหากับผลลัพธ์ของ ListView ที่อยู่ในลำดับกึ่งสุ่ม (ส่วนหัวแรกและรายการก็โอเคต่อไปนี้ยุ่งเหยิง) ฉันจัดการเพื่อค้นหาว่าปัญหาคืออะไร บล็อกของโค้ดที่อยู่ใต้'EDIT Better For Performance .. สามารถสังเกตเห็นได้เมื่อการเลื่อน'ทำให้ฉันสับสน - การลบสิ่งนี้ออกจากคลาส Custom ArrayAdapter ได้แก้ไขปัญหาให้ฉัน ฉันแนะนำให้ทุกคนที่ได้รับผลลัพธ์แบบสุ่มลองใช้สิ่งนี้ ขอบคุณสำหรับคำตอบที่ดีเยี่ยม ช่วยฉันได้จริงๆ!
blueprintchris

9

คุณอาจกำลังมองหาExpandableListViewซึ่งมีส่วนหัว (กลุ่ม) เพื่อแยกรายการ (ลูก)

กวดวิชาที่ดีในเรื่อง: ที่นี่


ฉันไม่ต้องการให้มันขยายได้
Rohit Malish

หากนั่นเป็นปัญหาเดียวคุณสามารถแทนที่เมธอด onItemClick เพื่อป้องกันการขยาย / ยุบมุมมอง
Saito Mea

แต่ฉันยังต้องการให้พวกเขาคลิกได้เพื่อจุดประสงค์อื่น
Rohit Malish

เอ่อ ... ที่จริงฉันตั้งใจจะบอกว่าonGroupClickจัดการคลิกที่ "ส่วนหัว" เท่านั้นและคุณไม่จำเป็นต้องปิดใช้งานการคลิกหรืออะไรทำนองนี้เพียงแค่ยกเลิกการดำเนินการยุบและตั้งค่าให้กลุ่มทั้งหมดขยายตั้งแต่เริ่มต้น
Saito Mea

ฉันยอมรับว่าExpandableListViewดีที่สุดในกรณีส่วนใหญ่ อย่างไรก็ตามฉันมีสถานการณ์ที่ฉันต้องการแสดงรายการแบบแบนในบางครั้งและรายการที่มีส่วนหัวในเวลาอื่น ๆ ในกิจกรรมของฉัน น่าเศร้าที่ExpandableListAdapterอินเทอร์เฟซไม่ขยายListAdapterส่วนต่อประสานดังนั้นสำหรับความหลากหลายฉันถูกบังคับให้ใช้โซลูชันของ @ antew
tytk

3

อีกทางเลือกหนึ่งคือมีไลบรารีของบุคคลที่สามที่ออกแบบมาสำหรับกรณีการใช้งานนี้โดยเฉพาะ คุณต้องสร้างส่วนหัวตามข้อมูลที่จัดเก็บในอะแดปเตอร์ พวกเขาเรียกว่าอะแดปเตอร์ Rolodex และใช้กับExpandableListViews. สามารถปรับแต่งให้ทำงานเหมือนรายการปกติที่มีส่วนหัวได้อย่างง่ายดาย

การใช้Eventอ็อบเจกต์ของ OP และการรู้ว่าส่วนหัวนั้นขึ้นอยู่กับสิ่งที่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

สิ่งที่ฉันทำให้วันที่ (เช่น 01 ธันวาคม 2016) เป็นส่วนหัว ฉันใช้ไลบรารี StickyHeaderListView

https://github.com/emilsjolander/StickyListHeaders

แปลงวันที่เป็นแบบยาวในหน่วยมิลลิวินาที [ไม่รวมเวลา] และกำหนดให้เป็นรหัสส่วนหัว

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

1

นี่คือโครงการตัวอย่างที่อิงตามคำตอบที่ละเอียดและเป็นประโยชน์ของ antew ซึ่งใช้ListViewส่วนหัวหลายตัวที่รวมตัวยึดมุมมองเพื่อปรับปรุงประสิทธิภาพการเลื่อน

ในโครงการนี้วัตถุที่เป็นตัวแทนในListViewกรณีของทั้งชั้นHeaderItemหรือชั้นเรียนซึ่งทั้งสองเป็นคลาสย่อยของระดับนามธรรมRowItem Itemแต่ละประเภทรองของสอดคล้องกับประเภทมุมมองที่แตกต่างกันในอะแดปเตอร์ที่กำหนดเองItem ItemAdapterเมธอดgetView()on ItemAdapterมอบหมายการสร้างมุมมองสำหรับแต่ละรายการให้เป็นgetView()วิธีการแบบรายบุคคลบนอย่างใดอย่างหนึ่งHeaderItemหรือRowItemขึ้นอยู่กับItemคลาสย่อยที่ใช้ในตำแหน่งที่ส่งไปยังgetView()เมธอดบนอะแด็ปเตอร์ แต่ละItemคลาสย่อยมีตัวยึดมุมมองของตัวเอง

ผู้ถือมุมมองดำเนินการดังนี้ getView()วิธีการในItemsubclasses ตรวจสอบว่าViewวัตถุที่ถูกส่งผ่านไปยังgetView()วิธีการในการItemAdapterเป็นโมฆะ View.setTag()ถ้าเป็นเช่นนั้นรูปแบบที่เหมาะสมจะพองและมุมมองวัตถุถือถูกสร้างและเชื่อมโยงกับมุมมองที่สูงเกินจริงผ่านทาง ถ้าวัตถุไม่ได้เป็นโมฆะแล้วมุมมองวัตถุถือได้รับการเชื่อมโยงกับมุมมองและมุมมองในฐานะผู้ถือถูกดึงผ่านView 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;
    }

}

นอกจากนี้ยังมีเค้าโครงรายการสองรายการหนึ่งรายการสำหรับคลาสย่อยของแต่ละรายการ นี่คือเค้าโครงที่headerใช้โดย HeaderItem:

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