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
YearExamGrouplist, with all its exam papers included. - Verify your ListView layout: Make sure it’s set to
match_parentfor 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

