Lesson 55. Header and Footer Listed. HeaderViewListAdapter

Lesson 55. Header and Footer Listed. HeaderViewListAdapter


In this lesson:

– we use Header and Footer in the lists
– Understand how and where HeaderViewListAdapter is used

Header and Footer (Hereinafter referred to as HF) are View, which can be added to the list from above and below. Creating the appropriate View for the list items is no longer the responsibility of the programmer but the adapter. He must create the View himself and provide it with a list of methods addHeader or addFooter.

These methods have two implementations. Consider the Header example.

1) addHeaderView (View v, Object data, boolean isSelectable)

v – View that appears as a list item
given – an object associated with this item in the list
isSelectable – whether you can click on or highlight an item

2) addHeaderView (View in)

Here is just a call to the first method with parameters: addHeaderView (v, null, true);

There is a nuance when using the HF and the adapter. When assigning a list adapter (SetAdapter method), the list checks if they have already been added Header or Footer.

if no, Then the list uses its adapter and prohibits later add HF. The same is written in the help of methods addHeader and addFooter – “Call this before calling setAdapter”. That is, you need to add HF before you assign a list adapter.

if yes, Then the list rotates the resulting adapter into HeaderViewListAdapter using the constructor: HeaderViewListAdapter (ArrayList headerViewInfos, ArrayList footerViewInfos, ListAdapter adapter), where headerViewInfos and footerViewInfos are previously added to the HF list as well adapter is the adapter we give to the list. And now the list methods will use adapter methods HeaderViewListAdapterThat is, both the HF and the adapter data that was assigned to the list will be used.

Let’s see in practice.

Let’s create a project:

Project name: P0551_HeaderFooter
Build Target: Android 2.3.3
Application name: HeaderFooter
Package name: ru.startandroid.develop.p0551headerfooter
Create Activity: MainActivity

To file strings.xml add rows:

Header
Footer
Test

screen main.xml:



    
    
    

Button and list.

Let’s create Layout files for Header and Footer.

header.xml



    
    
    
    

footer.xml



    
    
    
    

code MainActivity.java:

package ru.startandroid.develop.p0551headerfooter;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
  
  final String LOG_TAG = "myLogs";
  
  String[] data = {"one", "two", "three", "four", "five"};
  ListView lvMain;
  ArrayAdapter adapter;
  
  View header1;
  View header2;
  
  View footer1;
  View footer2;
  
  
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        lvMain = (ListView) findViewById(R.id.lvMain);
        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, data);
        
        // создаем Header и Footer
        header1 = createHeader("header 1");
        header2 = createHeader("header 2");
        footer1 = createFooter("footer 1");
        footer2 = createFooter("footer 2");
        
        fillList();
        
    }
    
 // формирование списка
    void fillList() {
    }
    
    // нажатие кнопки
    public void onclick(View v) {
    }
    
    // создание Header
    View createHeader(String text) {
      View v = getLayoutInflater().inflate(R.layout.header, null);
      ((TextView)v.findViewById(R.id.tvText)).setText(text);
      return v;
    }
    
    // создание Footer
    View createFooter(String text) {
      View v = getLayoutInflater().inflate(R.layout.footer, null);
      ((TextView)v.findViewById(R.id.tvText)).setText(text);
      return v;
    }    
}

IN onCreate preparing the adapter and HF elements.

IN fillList we will fill the list.

onclick – button press processing

createHeader and createFooter – Create a View for HF and populate them.

Let’s try to check that Header can really be added after installing the adapter. We implement the method fillList so:

 // формирование списка
    void fillList() {
          try {
          lvMain.setAdapter(adapter);
          lvMain.addHeaderView(header1);
          } catch (Exception ex) {
            Log.e(LOG_TAG, ex.getMessage());
          }
    }

Let’s save and run.

List items are. There is no Header.

We look at the log, we see an error there: “Cannot add header view to list – setAdapter has already been called». In Russian: cannot add Header, adapter already installed.

Let’s first add HF and then assign the adapter. change the code fillList:

 // формирование списка
    void fillList() {
      lvMain.addHeaderView(header1);
        lvMain.addHeaderView(header2, "some text for header 2", false);
        lvMain.addFooterView(footer1);
        lvMain.addFooterView(footer2, "some text for footer 2", false);
        lvMain.setAdapter(adapter);
    }

Notice what parameters we are adding header2 and footer2. We connect with them String objects and with false specify that highlighting these items will not work.

Save everything, launch the application.

HF appeared. Make sure clicking on header2 and footer2 does not lead to anything. And if you rotate the mouse wheel, the selection at these points does not stop.

By the way, if you make your adapter, then this effect can be achieved by implementing your isEnabled method.

Let’s try to remove HF. method onclick we will rewrite as follows:

  // нажатие кнопки
  public void onclick(View v) {
    lvMain.removeHeaderView(header2);
    lvMain.removeFooterView(footer2);
  }

For example, let’s click a button Test and we see that the HFs we have removed are gone – header2 and footer2.

Now let’s see how it works HeaderViewListAdapter, Let’s figure out what’s out there for the adapter attached to it and how to get to it.

rewrite the method onclick:

  // нажатие кнопки
  public void onclick(View v) {
    Object obj;
    HeaderViewListAdapter hvlAdapter = (HeaderViewListAdapter) lvMain.getAdapter();
    obj = hvlAdapter.getItem(1);
    Log.d(LOG_TAG, "hvlAdapter.getItem(1) = " + obj.toString());
    obj = hvlAdapter.getItem(4);
    Log.d(LOG_TAG, "hvlAdapter.getItem(4) = " + obj.toString());

    ArrayAdapter alAdapter = (ArrayAdapter) hvlAdapter.getWrappedAdapter();
    obj = alAdapter.getItem(1);
    Log.d(LOG_TAG, "alAdapter.getItem(1) = " + obj.toString());
    obj = alAdapter.getItem(4);
    Log.d(LOG_TAG, "alAdapter.getItem(4) = " + obj.toString());
  }

First, we are using the method getAdapter we get the adapter it uses ListView. Because we are added HF to the list, then it uses an adapter HeaderViewListAdapter. Let’s try to get the data on the second and fifth point of this adapter by calling getItem and output values ​​to the log.

Next we are from HeaderViewListAdapter we get it nested adapter. This is the adapter we gave to the list entry in the setAdapter method. But since HF was used, the list created HeaderViewListAdapter as the main adapter and gave it to us as a nested one and now we get it by getWrappedAdapter. Let’s try to get data from our adapter also on the second and fifth point and to log.

It is important to understand here that if we did not add HF to the list, then the list would not have gone awry with the creation of HeaderViewListAdapter and the lvMain.getAdapter method would immediately return ArrayAdapter.

Save, run, push a button Test and look at the log.

hvlAdapter.getItem (1) = some text for header 2
hvlAdapter.getItem (4) = three
alAdapter.getItem (1) = two
alAdapter.getItem (4) = five

The adapters showed different data. It happened because hvlAdapter integrates HF with data from alAdapter and works with them as with with one set data. AND alAdapter only takes into account your the data we gave him (array of data strings[]).

for hvlAdapter the second item is header2. When we added the Header, we assigned it a String object, and it is now logged. Fifth point – three.

for alAdapter the second item is two and the fifth item is five. He is not aware of any HF at all, he only works with his data.

Here’s how to work with Header and Footer elements. And about HeaderViewListAdapter in help it is written that developers most likely will not have to use this class directly in their code. Probably so it is. This class is used by the list to work with adapter data and added Header and Footer as a single data set.

For those who are upset that you cannot add HF after the list adapter is assigned, I will make an important amendment right away. Help is really written like this. But in reality, this only applies to Header. And Footer is added with no problems. And I don’t know if it’s a bug or a feature)

In the next lesson:

– we use Spinner




Discuss in the forum [17 replies]

Leave a Comment