Как я могу добавить липкий заголовок в мой ListView?

У меня есть listView, поэтому я хочу добавить липкий заголовок, чтобы он прилипал к вершине listView, и когда в listView начинается другая категория, другой заголовок занимает свое место, как контакты, где "a", как Липкий заголовок находится сверху, пока не появится «b». Есть ли какая-нибудь библиотека для этого? Я использую пользовательский адаптер списка, чтобы показать мой список ...

это мой пользовательский класс адаптера

public class NewsRowAdapter extends ArrayAdapter<Item>  {

private Activity activity;
private List<Item> items;
private Item objBean;
private int row;

private DisplayImageOptions options;
ImageLoader imageLoader;

public NewsRowAdapter(Activity act, int resource, List<Item> arrayList) {
    super(act, resource, arrayList);
    this.activity = act;
    this.row = resource;
    this.items = arrayList;



    imageLoader = ImageLoader.getInstance();
    File cacheDir1 = StorageUtils.getCacheDirectory(activity);

    ImageLoaderConfiguration config = new
    ImageLoaderConfiguration.Builder(activity)
    .maxImageWidthForMemoryCache(600)
    .maxImageHeightForMemoryCache(400)
    .httpConnectTimeout(5000)
    .httpReadTimeout(20000)
    .threadPoolSize(3)
    .threadPriority(Thread.MIN_PRIORITY + 3)
    .denyCacheImageMultipleSizesInMemory()
    .memoryCache(new UsingFreqLimitedMemoryCache(20000)) // You can pass your own memory cache implementation
    .discCache(new TotalSizeLimitedDiscCache(cacheDir1, 30000)) // You can pass your own disc cache implementation
    .defaultDisplayImageOptions(DisplayImageOptions.createSimple())
    .build();


    ImageLoader.getInstance().init(config);
//              imageLoader = ImageLoader;
//      

   options = new DisplayImageOptions.Builder()
    .showStubImage(R.drawable.icon2x)
    .showImageForEmptyUrl(R.drawable.icon2x).cacheInMemory()
    .cacheOnDisc().build();
//imageLoader = ImageLoader.getInstance();

}

@Override
public Item getItem(int position)
{
    return items.get(position);
}

@Override
public int getCount()
{
    return items.size();
}

@Override
public int getViewTypeCount()
{
    return 3;
}

@Override
public int getItemViewType(int position)
{
    Item item = items.get(position);
    if (item.isHeader())
    {
        return TYPE_SECTION_HEADER;
    }
    else
    {
        return TYPE_LIST_ITEM;
    }
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View view = convertView;
    ViewHolder holder;
    if (view == null) {
        LayoutInflater inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(row, null);

        holder = new ViewHolder();
        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }

    if ((items == null) || ((position + 1) > items.size()))
        return view;

    objBean = items.get(position);

    holder.tvName = (TextView) view.findViewById(R.id.title);
    holder.tvId = (TextView) view.findViewById(R.id.id);
    holder.tvFlag = (TextView) view.findViewById(R.id.flag);
    holder.tvimageurl=(TextView) view.findViewById(R.id.imageurl);
    holder.tvGender = (ImageView) view.findViewById(R.id.image);
    //holder.tvAge = (TextView) view.findViewById(R.id.tvage);
    holder.pbar = (ProgressBar) view.findViewById(R.id.pbar);
    if (holder.tvName != null && null != objBean.getName()
            && objBean.getName().trim().length() > 0) {
        holder.tvName.setText(Html.fromHtml(objBean.getName()));
    }
    if (holder.tvId != null && null != objBean.getId()
            && objBean.getId().trim().length() > 0) {
        holder.tvId.setText(Html.fromHtml(objBean.getId()));

    }
    if (holder.tvFlag != null && null != objBean.getFlag()
            && objBean.getFlag().trim().length() > 0) {
        holder.tvFlag.setText(Html.fromHtml(objBean.getFlag()));

    }

    if (holder.tvimageurl != null && null != objBean.getGender()
            && objBean.getFlag().trim().length() > 0) {
        holder.tvimageurl.setText(Html.fromHtml(objBean.getGender()));

    }

    //if (holder.tvBDate != null && null != objBean.getBirthdate()
    //      && objBean.getBirthdate().trim().length() > 0) {
    //  holder.tvBDate.setText(Html.fromHtml(objBean.getBirthdate()));
    //}
    if (holder.tvGender != null) {
        if (null != objBean.getGender()
                && objBean.getGender().trim().length() > 0) {
            final ProgressBar pbar = holder.pbar;


            imageLoader.displayImage(objBean.getGender(), holder.tvGender,
                    options, new ImageLoadingListener() {

                        @Override
                        public void onLoadingComplete() {
                            pbar.setVisibility(View.INVISIBLE);

                        }


                        @Override
                        public void onLoadingFailed() {
                            pbar.setVisibility(View.INVISIBLE);
                        }


                        @Override
                        public void onLoadingStarted() {
                            pbar.setVisibility(View.INVISIBLE);

                        }
                    });

        } else {
            holder.tvGender.setImageResource(R.drawable.icon2x);
        }
    }


    return view;
}

public class ViewHolder {
    public TextView tvimageurl;
    public TextView tvFlag;
    public TextView tvId;
    public ProgressBar pbar;
    public TextView tvName, tvCity, tvBDate, tvAge;
    ImageView tvGender;
}


}

нужна помощь.....

Ответы на вопрос(2)

Ваш ответ на вопрос