Как добавить липкий заголовок в свой 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; } } 

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

Я долгое время пытался писать свой собственный StickyHeader, поскольку StickyListHeaders git не соответствовал моим потребностям. Однако StickyListHeaders помогают мне в понимании того, как это сделать, и поэтому писатель StickyListHeaders заслуживает упоминания об этом.

Многие вещи должны быть объединены, чтобы работать с липким заголовком.

Сначала объявите следующее

 private TextView mStickyHeader; private TextView mStickyHeader2; private int mCurrentStickyHeaderSection; 

В onActivityCreated

 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ... mCurrentStickyHeaderSection = -1; mStickyHeader = (TextView) getView().findViewById(R.id.textview_sticky_header_section); mStickyHeader2 = (TextView) getView().findViewById(R.id.textview_sticky_header_section_2); mListView = (ListView) getView().findViewById(R.id.listView_with_sticky_headers); mListView.setOnScrollListener(new OnScrollListener() { @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { updateStickyHeader(firstVisibleItem); } @Override public void onScrollStateChanged(AbsListView arg0, int arg1) { // TODO Auto-generated method stub } }); 

Я предполагаю, что вы написали CustomAdapter с индексами раздела и сосредоточитесь только на липких заголовках.

Следующий метод содержит все, что вам нужно, чтобы иметь stickyheader. firstVisibleItem частью является определение, является ли firstVisibleItem заголовком (pos = -1) или нет, и соответствующий раздел. Эта часть может потребовать вас несколько раз, чтобы она работала правильно.

 private void updateStickyHeader(int firstVisibleItem) { // here is the tricky part. You have to determine pos and section // pos is the position within a section pos = -1 means it's the header of the section // you have to determine if firstVisibleItem is a header or not // you also have to determine the section to which belongs the first item int pos = whatIsThePositionOfTheItem[firstVisibleItem]; int section = whatIsTheSectionOfTheItem[firstVisibleItem]; if (section != mCurrentStickyHeaderSection) { mStickyHeader.setText("Your_Previous_Section_Text"); mStickyHeader2.setText("Your_Next_Section_Text"); mCurrentStickyHeaderSection = section; } int stickyHeaderHeight = mStickyHeader.getHeight(); if (stickyHeaderHeight == 0) { stickyHeaderHeight = mStickyHeader.getMeasuredHeight(); } View SectionLastView = mListView.getChildAt(0); if (SectionLastView != null && pos == -1 && SectionLastView.getBottom() <= stickyHeaderHeight) { int lastViewBottom = SectionLastView.getBottom(); mStickyHeader.setTranslationY(lastViewBottom - stickyHeaderHeight); mStickyHeader2.setTranslationY(lastViewBottom - stickyHeaderHeight + mStickyHeader.getHeight()); } else if (stickyHeaderHeight != 0) { mStickyHeader.setTranslationY(0); mStickyHeader2.setTranslationY(mStickyHeader.getHeight()); } } 

Наконец, макет должен содержать framelayout и должен выглядеть так

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > //this textview is just a global title of your listview if you need one but can be remove <TextView android:id="@+id/textview_title" style="?android:attr/listSeparatorTextViewStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="6dp" android:paddingRight="6dp" android:textIsSelectable="False" /> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/textview_sticky_header_section" style="?android:attr/listSeparatorTextViewStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="6dp" android:paddingRight="6dp" android:textIsSelectable="False" /> <TextView android:id="@+id/textview_sticky_header_section_2" style="?android:attr/listSeparatorTextViewStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="6dp" android:paddingRight="6dp" android:textIsSelectable="False" /> </FrameLayout> <ListView android:id="@+id/listView_with_sticky_header" android:layout_width="match_parent" android:layout_height="wrap_content" android:fastScrollEnabled="true" android:longClickable="true" > </ListView> </LinearLayout> 

Обновить

Как уже было whatIsThePositionOfTheItem в комментариях, это объяснение того, что такое whatIsThePositionOfTheItem и whatIsTheSectionOfTheItem . Эти методы должны возвращать position и section данного элемента.

В моем случае это было довольно просто, мои данные уже содержали section и position . На самом деле, я показываю текст, и текст начинается с section и position . Поэтому я просто разбираю этот текст, чтобы определить section и position .

Для других трудно привести пример, потому что это действительно зависит от того, что вы показываете. Но, чтобы сделать длинную историю коротким, whatIsThePositionOfTheItem и whatIsTheSectionOfTheItem должны вернуть позицию и раздел данного элемента. Вам, вероятно, придется заполнить таблицу position и section каждого элемента в вашем списке и получить position и section из этой таблицы.

Существует библиотека с таким именем, которая реализует то, что вы хотите:

Демоверсия библиотеки

Вы можете проверить это здесь: https://github.com/emilsjolander/StickyListHeaders

Intereting Posts
Будет handler.post (новый Runnable ()); Создать новую тему в Android? Реализация TabListener с использованием библиотеки поддержки Проблема sqlite onCreate () Я хочу, чтобы моя база данных создавалась один раз, и она не будет изменяться, но я не могу создать данные, когда я в onCreate () Просмотр списка Android исчезает после поворота экрана Автоматическое форматирование кода в Android Studio Ошибка отображения ящика чертежа в редакторе макетов ADT Android 4.0.4 MediaPlayer готовят выпуск с использованием URL-адресов RTSP Выполнение полупараллельного теста Espresso не выполняется на статических объектах? «ZipAlignExe« не существует ». Ошибка при запуске моего проекта в Android Studio Как изменить настольное приложение Android по умолчанию? Изменение размера поверхности для изменения соотношения сторон в видеоизображении в андроиде Как получить кнопку для открытия другой активности в Android Studio? Как читать pdf в приложении для Android? Могу ли я копировать между CouchBase на Android и Couch DB, работающим в Linux? Студия Android / Gradle build не работает в выпуске: не удалось определить зависимости задачи: app: crashlyticsStoreDeobsRelease '