How to add several kinds of headers in ListView

I have a custom adapter for my ListView . I want to add project names as the headers of my work requests. Adding one title works fine, but I'm not sure how to add multiple titles using addHeaderView . I don’t understand where exactly to place the setAdapter or is it supposed that it will be placed several times?

This is my java code for a single header that works:

 mListView = (ListView)findViewById(R.id.dashboardList); View header1 = getLayoutInflater().inflate(R.layout.listview_header, null, false); tv = (TextView) header1.findViewById(R.id.listHeader); adapter = new MyCustomAdapter(MyDashboardActivity.this, R.layout.mydashboard_row, dashboardBean); tv.setText("Project 1"); mListView.addHeaderView(header1, null, false); for (int i=0; i < 7; i++) { dashboardBean.add(new DashboardBean(workRequests[i],status[i],actualHours[i])); } mListView.setAdapter(adapter); 

Now, for two headings, I tried this:

 mListView = (ListView)findViewById(R.id.dashboardList); View header1 = getLayoutInflater().inflate(R.layout.listview_header, null, false); tv = (TextView) header1.findViewById(R.id.listHeader); adapter = new MyCustomAdapter(MyDashboardActivity.this, R.layout.mydashboard_row, dashboardBean); tv.setText("RxOffice"); mListView.addHeaderView(header1, null, false); for (int i=0; i < 4; i++) { dashboardBean.add(new DashboardBean(workRequests[i],status[i],actualHours[i])); } tv.setText(Project 2"); mListView.addHeaderView(header1, null, false); for (int i=4; i < workRequests.length; i++) { dashboardBean.add(new DashboardBean(workRequests[i],status[i],actualHours[i])); } mListView.setAdapter(adapter); 

But that will not work! This only gives me the title of Project 2 and all 7 entries below. Can someone tell me what happened? I assume this has something to setAdapter with setAdapter . Thanks!

+6
source share
3 answers

I don’t think you want to do the way you try to do it. When you use addHeaderView , it wraps your ListAdapter in a HeaderViewListAdapter . I looked at the docs for here , and that seems to imply that you can have multiple headers, but they will all be on top (duh, heading).

It seems like what you really want is secateurs ...

You can use the CommonWare MergeAdapter . It will allow you to insert adapters and views (in any order) and present them as one adapter in a list. You simply pass the headers and adapters for each section of the content, and then set it to your list.

Pseudo-code example:

 myMergeAdapter = new MergeAdapter(); myMergeAdapter.addView(HeaderView1); myMergeAdapter.addAdapter(listAdapter1); myMergeAdapter.addView(HeaderView2); myMergeAdapter.addAdapter(listAdapter2); setListAdapter(myMergeAdapter); 
+11
source

I got several header scripts using the custom Section Adapter that was originally encoded by CommonsWare , you can make a section in the list, for example Books, Games, etc. check the code below.

Section adapter:

 package com.medplan.db; import java.util.ArrayList; import java.util.List; import android.view.View; import android.view.ViewGroup; import android.widget.Adapter; import android.widget.BaseAdapter; abstract public class SectionedAdapter extends BaseAdapter { String TAG = "========SectionedAdapter============"; abstract protected View getHeaderView(String caption, int index, View convertView, ViewGroup parent); private List<Section> sections=new ArrayList<Section>(); private static int TYPE_SECTION_HEADER=0; public SectionedAdapter() { super(); sections.clear(); } public void addSection(String caption, Adapter adapter) { sections.add(new Section(caption, adapter)); } public void clear() { sections.clear(); notifyDataSetChanged(); } public Object getItem(int position) { for (Section section : this.sections) { if (position==0) { return(section); } int size=section.adapter.getCount()+1; if (position<size) { return(section.adapter.getItem(position-1)); } position-=size; } return(null); } public int getCount() { int total=0; for (Section section : this.sections) { total+=section.adapter.getCount()+1; // add one for header } return(total); } public int getViewTypeCount() { int total=1; // one for the header, plus those from sections for (Section section : this.sections) { total+=section.adapter.getViewTypeCount(); } return(total); } public int getItemViewType(int position) { int typeOffset=TYPE_SECTION_HEADER+1; // start counting from here for (Section section : this.sections) { if (position==0) { return(TYPE_SECTION_HEADER); } int size=section.adapter.getCount()+1; if (position<size) { return(typeOffset+section.adapter.getItemViewType(position-1)); } position-=size; typeOffset+=section.adapter.getViewTypeCount(); } return(-1); } public boolean areAllItemsSelectable() { return(false); } public boolean isEnabled(int position) { return(getItemViewType(position)!=TYPE_SECTION_HEADER); } public View getView(int position, View convertView, ViewGroup parent) { int sectionIndex=0; for (Section section : this.sections) { if (position==0) { return(getHeaderView(section.caption, sectionIndex, convertView, parent)); } int size=section.adapter.getCount()+1; if (position<size) { return(section.adapter.getView(position-1,convertView,parent)); } position-=size; sectionIndex++; } return(null); } public long getItemId(int position) { return(position); } class Section { String caption = null; Adapter adapter = null; Section(String caption, Adapter adapter) { this.caption=caption; this.adapter=adapter; } } } 

Inside the action, make the section adapter object, see the code below:

 final SectionedAdapter adapter =new SectionedAdapter() { protected View getHeaderView(String caption, int index, View convertView,ViewGroup parent) { result=(TextView)convertView; if (convertView==null) { result=(TextView)getLayoutInflater().inflate(R.layout.section_header,null); } result.setText(caption); // temp=caption; // ind=index; return(result); } }; 

section_header.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="wrap_content" android:background="@color/black" android:textColor="#FFFFFF" android:ellipsize="end" android:textSize="11sp" style="?android:attr/listSeparatorTextViewStyle" /> <!-- android:background="#515050"--> 

In the "Activity" section, add the section as much as you want:

Note: userPic and medPic are the name of arraylist.

 adapter.addSection("section first", new EfficientAdapter(getApplicationContext(),usersPic)); adapter.addSection("section second", new EfficientAdapter(getApplicationContext(),medPic)); listview.setAdapter(adapter); 
+2
source

I would solve this problem using ExpandableListView. This does not require an additional library.

  • Create your own adapter.
  • Give your details and fill in the methods you need to override.
  • After installing the adapter using ExpandableListView:
    • Override groupItemClick so that clicking on groups does not actually expand the view.
    • Scroll through all the parent elements in the adapter and set them extended.
0
source

Source: https://habr.com/ru/post/918995/


All Articles