SoFunction
Updated on 2025-03-02

Implementation methods for dynamic display and hidden headerview in Android ListView

Implementation methods for dynamic display and hidden headerview in Android ListView

1. How to dynamically set headerview

There are two ideas for dynamically setting headerview.

Method 1

Write the header layout in the layout file of the list item, and dynamically control its display or hidden by determining whether the position value is 0 in the adapter.

Code example:

Layout file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="@drawable/item_selector"
  android:gravity="center_vertical"
  android:orientation="vertical" >
  <include
    android:
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    layout="@layout/view_header"
    android:visibility="gone" />
  <LinearLayout
    android:
    android:layout_width="match_parent"
    android:layout_height="67dip"
    android:gravity="center_vertical"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:orientation="horizontal" >
    ...

  </LinearLayout>

</LinearLayout>

It is mainly divided into two parts. The above view_header is the layout of the header, and the below view_item is the layout of the ordinary item. The specific layout content is omitted here. Then handle the display problem of the header in the getView method. If the position is 0, the header will be displayed and the ordinary item will be hidden. If the position is greater than 0, the header is hidden and the normal item is hidden.

    @Override
    public View getView(int position, View convertView, ViewGroup parent)     

      ...

      if (position == 0) {
        ();
        ();
        initHeaderView(convertView);
      } else {
        ();
        ();
        initNormalView(convertView);
      }
      return convertView;

To expand this way, if there are two different headviews, a new judgment condition is added:

 if (position == 0) {
        ();
        holder.();
        ();
        initHeaderView(convertView);
      } else if(position == 1){
        ();
        holder.();
        ();
        initHeaderView2(convertView);
      }else {
        ();
        ();
        holder.();
        initNormalView(convertView);
      }

Method 2

Use the addHeaderView provided by listview

In order to dynamically display and hide the header, according to convention, it is mistakenly believed that it can be achieved directly through the setVisibility. However, it is not found in actual use. For example:

private View mHeader;
mHeader = (this).inflate(, null); //Load footer layout(mHeader);

If you want to hide this header dynamically, inertial thinking is to directly set the header to gone: (In fact, it is wrong to do this)

(); //hideheader

In fact, after setting GONE directly, although the element is hidden, it still occupies that area, and the effect is the same as the one at this time.

The solution is to put another layer of LinearLayout/RelativeLayout on the outermost layer of the header layout file, which is called headerParent here. Hide mHeader when hidden, not headerParent.

view_header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:andro
  android:
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="#FFFFFF"
  android:gravity="center"
  android:orientation="vertical"
  >
  <LinearLayout
    android:
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center">

    ...

  </LinearLayout>
</LinearLayout>

Loading the layout of header and headerParent:

Key code display

private View mHeader; //header
private View mHeaderParent; //There is another layer of LinearLayout on the outermost part of the header
mHeaderParent = (getActivity()).inflate(.headerparent_listview, null);//Load footerParent layoutmHeader = ();
(mHeaderParent); //Put mHeaderParent into ListView(); 

Set header to gone: (not setting headerParent to gone)

();

One thing to note about in this method is that the () method must be called before the setAdapter() method, otherwise an exception will be thrown.

ListView listView = xxxx; 
 (mHeaderParent); 
 (adapter); 
 ();

The above two methods have their own advantages and disadvantages. I personally prefer the second method. The first method is too coupled. Since the header layout is combined with the ordinary item layout, and the conditional judgment of position is added every time it is displayed, there is some additional performance consumption.

2. Problems caused by introducing headerview

When the headerview is introduced, the position shift problem of OnItemClickListener may be caused.

The position usually starts from 0, but after adding the HeaderView, the position will also calculate the number of HeaderViews.

Here are two solutions:

(1). Manually calculate the real position position:

final headerCount = 1;
(new OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> parent, View view,
      int position, long id) {
    Item item = (position - headerCount);
  }
});

(2).ListView has provided us with data binding:

(new OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> parent, View view,
      int position, long id) {
    Item item = ().getItem(position);
  }
});

If you have any questions, please leave a message or go to the community of this site to exchange and discuss. Thank you for reading. I hope it can help you. Thank you for your support for this site!