You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android开发:ListView中实现年份对应多份真题的适配器设置问题

Hey there! Let's fix that grouped ListView issue you're facing—displaying a year only once with multiple corresponding exam papers is a classic grouped list scenario, and I’ll walk you through adjusting your adapter to make it work exactly as you want.

1. First, Restructure Your Data for Grouping

First, we need to organize your WebService data into a grouped structure so the adapter can easily distinguish between year headers and their associated exam papers. Create a simple model class to hold each year group:

public class YearExamGroup {
    private String year;
    private List<String> examPapers;

    // Constructor, getters, and setters
    public YearExamGroup(String year, List<String> examPapers) {
        this.year = year;
        this.examPapers = examPapers;
    }

    public String getYear() { return year; }
    public List<String> getExamPapers() { return examPapers; }
}

Once you fetch data from your WebService, convert the raw response into a List<YearExamGroup>—each entry will represent one year and all its linked exam papers.

2. Build a Flexible List Item Layout

Create a single list item layout (list_item_exam.xml) that can handle both year headers and exam paper entries by toggling visibility:

<?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:orientation="vertical"
    android:padding="16dp">

    <!-- Year Header TextView - hidden by default -->
    <TextView
        android:id="@+id/tv_year"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textStyle="bold"
        android:visibility="gone"/>

    <!-- Exam Paper TextView -->
    <TextView
        android:id="@+id/tv_exam_paper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:paddingTop="8dp"
        android:paddingStart="16dp"/>

</LinearLayout>

3. Implement the Custom Adapter

The key is to create an adapter that can recognize whether an item is a year header or an exam paper. We’ll flatten our grouped data into a single list to simplify position handling:

public class ExamListAdapter extends BaseAdapter {
    private Context mContext;
    private List<Object> mFlattenedData; // Holds year strings + exam paper strings

    public ExamListAdapter(Context context, List<YearExamGroup> groupedData) {
        mContext = context;
        mFlattenedData = new ArrayList<>();
        
        // Flatten the grouped data: add year first, then all its exam papers
        for (YearExamGroup group : groupedData) {
            mFlattenedData.add(group.getYear());
            mFlattenedData.addAll(group.getExamPapers());
        }
    }

    @Override
    public int getCount() {
        return mFlattenedData.size();
    }

    @Override
    public Object getItem(int position) {
        return mFlattenedData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_exam, parent, false);
            holder = new ViewHolder();
            holder.tvYear = convertView.findViewById(R.id.tv_year);
            holder.tvExamPaper = convertView.findViewById(R.id.tv_exam_paper);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        Object item = getItem(position);
        if (item instanceof String) {
            // This is a year header
            holder.tvYear.setVisibility(View.VISIBLE);
            holder.tvYear.setText((String) item);
            holder.tvExamPaper.setVisibility(View.GONE);
        } else {
            // This is an exam paper entry
            holder.tvYear.setVisibility(View.GONE);
            holder.tvExamPaper.setVisibility(View.VISIBLE);
            holder.tvExamPaper.setText((String) item);
        }

        return convertView;
    }

    // ViewHolder to optimize view recycling
    static class ViewHolder {
        TextView tvYear;
        TextView tvExamPaper;
    }
}

4. Attach the Adapter to Your ListView

In your Activity, after processing the WebService data into List<YearExamGroup>, set up the adapter:

// Assume you've parsed WebService data into this grouped list
List<YearExamGroup> groupedExamData = new ArrayList<>();
// Populate groupedExamData with your WebService response...

ListView examListView = findViewById(R.id.your_listview_id);
ExamListAdapter adapter = new ExamListAdapter(this, groupedExamData);
examListView.setAdapter(adapter);

Quick Troubleshooting Tips

  • Double-check your data grouping: Ensure each year only appears once in the YearExamGroup list, with all its exam papers included.
  • Verify your ListView layout: Make sure it’s set to match_parent for width so it isn’t squeezed by the right panel.
  • If you’re open to modern alternatives, RecyclerView with multiple ViewHolder types offers better performance for grouped lists—but the above ListView solution will work perfectly for your current setup.

内容的提问来源于stack exchange,提问作者M.Usama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:58:30