Java 带标题的Android多行列表视图

Java 带标题的Android多行列表视图,java,android,android-listview,Java,Android,Android Listview,我需要在Android中创建一个具有标题且多行的ListView。我用它来显示作业标题及其下方的截止日期。作业分为两个标题:“即将完成的作业”和“过去的作业”(当然是基于日期) 我的标题工作正常,作业标题显示正确,但如何将第二行合并到列表中,我感到困惑 这是我的密码: ListCourseAssignments.java @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInsta

我需要在Android中创建一个具有标题且多行的
ListView
。我用它来显示作业标题及其下方的截止日期。作业分为两个标题:“即将完成的作业”和“过去的作业”(当然是基于日期)

我的标题工作正常,作业标题显示正确,但如何将第二行合并到列表中,我感到困惑

这是我的密码:

ListCourseAssignments.java

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    final SeparatedListAdapter adapter;
    setContentView(R.layout.courseassignmentslistview);
    adapter = new SeparatedListAdapter(getContext());
    ArrayAdapter<String> upcomingList = new ArrayAdapter<String>(getContext(), R.layout.list_item, Homework.getUpcomingDates()); // Homework.getUpcomingDates() Returns string array
    ArrayAdapter<String> pastList = new ArrayAdapter<String>(getContext(), R.layout.list_item, Homework.getPastDates()); // Homework.getPastDates() Returns string array

    adapter.addSection("Upcoming Assignments", upcomingList); 
    adapter.addSection("Past Assignments", pastList);

    ListView lv = (ListView) findViewById(android.R.id.list);
    lv.setAdapter(adapter);

    lv.setOnItemClickListener(new OnItemClickListener(){
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long duration){
            String item = (String) adapter.getItem(position);
            Toast.makeText(getApplicationContext(), item, Toast.LENGTH_SHORT).show();
        }
    });
}
@覆盖
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
最终分离列表适配器;
setContentView(R.layout.courseassignmentslistview);
adapter=新的SeparatedListAdapter(getContext());
ArrayAdapter upcomingList=新的ArrayAdapter(getContext(),R.layout.list_项,家庭作业.getUpcomingDates());//家庭作业.getUpcomingDates()返回字符串数组
ArrayAdapter pastList=新的ArrayAdapter(getContext(),R.layout.list_项,家庭作业.getPastDates());//家庭作业.getPastDates()返回字符串数组
adapter.addSection(“即将完成的任务”,上传列表);
adapter.addSection(“过去的任务”,过去的列表);
ListView lv=(ListView)findViewById(android.R.id.list);
低压设置适配器(适配器);
lv.setOnItemClickListener(新的OnItemClickListener(){
@凌驾
public void onItemClick(AdapterView父视图、视图视图、整型位置、长持续时间){
字符串项=(字符串)适配器.getItem(位置);
Toast.makeText(getApplicationContext(),item,Toast.LENGTH_SHORT.show();
}
});
}
SeparatedListAdapter.java

public class SeparatedListAdapter extends BaseAdapter {
public final Map<String, Adapter> sections = new LinkedHashMap<String, Adapter>();
public final ArrayAdapter<String> headers;

public SeparatedListAdapter(Context context) {
    headers = new ArrayAdapter<String>(context, R.layout.courseassignmentslistview_header);
}

public void addSection(String section, Adapter adapter) {
    this.headers.add(section);
    this.sections.put(section, adapter);
}

public Object getItem(int position) {
    for (Object section : this.sections.keySet()) {
        Adapter adapter = sections.get(section);
        int size = adapter.getCount() + 1;

        if (position == 0) return section;
        if (position < size) return adapter.getItem(position - 1);

        position -= size;
    }
    return null;
}

public int getCount() {
    int total = 0;
    for (Adapter adapter : this.sections.values()) total += adapter.getCount() + 1;
    return total;
}

@Override
public int getViewTypeCount() {
    int total = 1;
    for (Adapter adapter : this.sections.values()) total += adapter.getViewTypeCount();
    return total;
}

@Override
public int getItemViewType(int position) {
    int type = 1;
    for (Object section : this.sections.keySet()) {
        Adapter adapter = sections.get(section);
        int size = adapter.getCount() + 1;

        if (position == 0) return 0;
        if (position < size) return type + adapter.getItemViewType(position - 1);

        position -= size;
        type += adapter.getViewTypeCount();
    }
    return -1;
}

public boolean areAllItemsSelectable() {
    return false;
}

@Override
public boolean isEnabled(int position) {
    return (getItemViewType(position) != 0);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int sectionnum = 0;
    for (Object section : this.sections.keySet()) {
        Adapter adapter = sections.get(section);
        int size = adapter.getCount() + 1;

        if (position == 0) return headers.getView(sectionnum, convertView, parent);
        if (position < size) return adapter.getView(position - 1, convertView, parent);

        position -= size;
        sectionnum++;
    }
    return null;
}

@Override
public long getItemId(int position) {
    return position;
}
}
public类SeparatedListAdapter扩展了BaseAdapter{
公共最终映射节=新建LinkedHashMap();
公共最终阵列适配器标头;
公共分隔的ListAdapter(上下文){
headers=newarrayadapter(context,R.layout.courseassignmentslistview_头);
}
public void addSection(字符串段、适配器){
此.headers.add(节);
此.sections.put(节,适配器);
}
公共对象getItem(int位置){
for(对象节:this.sections.keySet()){
适配器=节。获取(节);
int size=adapter.getCount()+1;
如果(位置==0)返回段;
if(位置<大小)返回适配器.getItem(位置-1);
位置-=大小;
}
返回null;
}
public int getCount(){
int-total=0;
对于(适配器适配器:this.sections.values())total+=Adapter.getCount()+1;
返回总数;
}
@凌驾
public int getViewTypeCount(){
整数合计=1;
for(适配器适配器:this.sections.values())总计+=Adapter.getViewTypeCount();
返回总数;
}
@凌驾
public int getItemViewType(int位置){
int型=1;
for(对象节:this.sections.keySet()){
适配器=节。获取(节);
int size=adapter.getCount()+1;
如果(位置==0)返回0;
if(位置<大小)返回类型+适配器.getItemViewType(位置-1);
位置-=大小;
类型+=适配器。getViewTypeCount();
}
返回-1;
}
公共布尔值areAllItemsSelectable(){
返回false;
}
@凌驾
公共布尔值isEnabled(整型位置){
返回(getItemViewType(位置)!=0);
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
int sectionnum=0;
for(对象节:this.sections.keySet()){
适配器=节。获取(节);
int size=adapter.getCount()+1;
if(position==0)返回headers.getView(sectionnum,convertView,parent);
if(position
courseassignmentslistview_header.xml

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/list_header_title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingTop="2dip"
    android:paddingBottom="2dip"
    android:paddingLeft="5dip"
    style="?android:attr/listSeparatorTextViewStyle" />

courseassignmentslistview.xml

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

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

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="16sp" >
</TextView>


编辑:我知道如何使用多行创建列表,但我不知道如何将其与带有标题的列表(如此)组合在一起。

我不知道如何使用您目前拥有的内容,但您可以使用CommonWare的MergeAdapter

引用自述:

MergeAdapter accepts a mix of Adapters and Views and presents them as one contiguous 
whole to whatever ListView it is poured into. This is good for cases where you have
multiple data sources, or if you have a handful of ordinary Views to mix in with lists 
of data, or the like.
你可以得到它

我写了一篇关于使用它的简要概述


使用MergeAdapter,您可以通过为节标题提供视图来使用它,然后设置适配器以创建所需的两行格式。

对不起,也许我应该更清楚地说明这一点,但在列表中添加第二行不是问题。问题是我不知道如何在添加第二行的同时添加标题。谢谢你的帮助。这看起来很有希望。谢谢好吧,我有点麻烦。出于某种原因,我得到了一个运行时异常,从堆栈跟踪判断,它与我的代码没有任何特定关系。“java.lang.RuntimeException您必须覆盖com.commonware.cwac.sacklist.SackOfViewsAdapter.newView(SackOfViewsAdapter.java:187)中com.commonware.cwac.SackOfViewsAdapter.getView(SackOfViewsAdapter.java:147)中com.commonware.cwac.merge.MergeAdapter.getView(MergeAdapter.java:243)中的newView()我以前没见过。翻阅文档,没有提到任何类似的事情……如果你继续有问题,你可以发布,Commonware可能会回应。他在那个存储库上有关于如何吸引他的注意力的说明。