Reputation: 749
My question is not about adding a Sticky header in a ListView
in Android, I want to ask how it actually works ?
I know that there are so many sticky headers libraries available on github like,
http://applidium.github.io/HeaderListView/#how_to_use
and
https://github.com/emilsjolander/StickyListHeaders
and I know that the views of the ListView
in android are recycled, which means there are only enough views are generated that are required to fill the screen + one for the previous and one for the next, and these views are recycled and re used when we scroll up and down.
but Why do someone need to write an entire library just to add a simple Section Header in a List view why can't it be done more simply, and how does these section headers work ?
Aren't they recycled along with the views of the List items ?
shouldn't there be an approach through which we can simply say that certain view must stay at the top all the time and only updates when we explicitly tell them to update without using any 3rd party library ?
Upvotes: 0
Views: 1573
Reputation: 8338
Well, the code for the entire library is available in the links that you provided. Go ahead and take a look!
They build off of the normal ListView
, so the idea is completely the same. You still have an adapter
that holds the data, which is then added to your custom ListView
. The ListView
still only holds as many views as are shown on the screen at a time (to be more efficient). The difference comes in the way that the added items are handled.
Each item that you pass in (through the adapter
) returns a "Header ID" to which it is mapped. Items with the same header ID are grouped under the same header. These headers are created with a getHeaderView()
method in your adapter, based on the data that you passed in.
The sample code shows this pretty well, from the library link:
public class MyAdapter extends BaseAdapter implements StickyListHeadersAdapter {
private String[] countries;
private LayoutInflater inflater;
public TestBaseAdapter(Context context) {
inflater = LayoutInflater.from(context);
countries = context.getResources().getStringArray(R.array.countries);
}
@Override
public int getCount() {
return countries.length;
}
@Override
public Object getItem(int position) {
return countries[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.test_list_item_layout, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(countries[position]);
return convertView;
}
@Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = inflater.inflate(R.layout.header, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (HeaderViewHolder) convertView.getTag();
}
//set header text as first char in name
String headerText = "" + countries[position].subSequence(0, 1).charAt(0);
holder.text.setText(headerText);
return convertView;
}
@Override
public long getHeaderId(int position) {
//return the first character of the country as ID because this is what headers are based upon
return countries[position].subSequence(0, 1).charAt(0);
}
class HeaderViewHolder {
TextView text;
}
class ViewHolder {
TextView text;
}
}
Upvotes: 1