Приховати вигляд нижнього колонтитула в ListView?


78

У мене є ListView. Дані, що стоять за цим, отримуються з Інтернету, наборами з 10-30 предметів, щоразу, коли користувач прокручує до кінця. Для того, щоб вказати, що завантажується більше предметів, я addFooterView()додав простий вигляд, який відображає повідомлення "Завантаження ..." та обертання. Тепер, коли у мене не вистачає даних (більше немає даних для отримання), я хочу приховати це повідомлення. Я намагався зробити:

loadingView.setVisibility(View.GONE);

На жаль, хоча це і приховує погляд, воно залишає для нього простір. Тобто у мене закінчується великий порожній простір, де раніше було повідомлення "Завантаження". Як я можу правильно приховувати цей погляд?

Я не можу використовувати, removeFooterView()тому що мені, можливо, доведеться показати його знову, і в цьому випадку я не можу зателефонувати addFooterView()знову, оскільки адаптер вже встановлений на ListView, і ви не можете зателефонувати addHeaderView()/addFooterView() після встановлення адаптера.

Відповіді:


84

Здається, вам дозволено дзвонити addHeaderView()/ addFooterView() після того setAdapter() , як ви хоча б раз раніше викликали один із цих методів . Це досить погане дизайнерське рішення від Google, тому я подав запитання . Поєднайте це, removeFooterView()і у вас є моє рішення.

+1 для двох інших відповідей, які я отримав, вони є дійсними (і, можливо, більш правильними) рішеннями. Однак моя найпростіша, і мені подобається простота, тому я позначу власну відповідь як прийняту.


6
Здається, це не працює для заголовків. Я можу додати нижній колонтитул після setAdapter, але не заголовок.
cottonBallPaws

1
+1 за збереження ВЕЛИЧЕЗНОГО головного болю. Цікаво, скільки часу мені знадобилося б, щоб зрозуміти, що вам довелося додати нижній колонтитул перед налаштуванням адаптера. (німий)
Росс Хембрік,

Я помітив, що позиція прокрутки скидається, коли ви видаляєте нижню, тому, коли ви прокручуєте -> нижній колонтитул видаляється, перш ніж закінчити розгортання, він переходить назад до кінця списку. Ви натрапили на це?
Вадим Перетокін

Не зважаючи на це, я зіткнувся з тим самим питанням, що і малоFluffyKitty. Йти доведеться з користувацьким адаптером.
Вадим Перетокін

Чудова відповідь, проста! +100 за подання проблем із Google.
Томаш,

37

Спробуйте встановити висоту нижнього колонтитула на 0px або 1px, перш ніж приховувати його. Крім того, оберніть вигляд нижнього колонтитула у wrap_contentвисоту FrameLayoutта приховайте / покажіть внутрішній вигляд, залишаючи FrameLayoutвидимим; тоді висота повинна правильно обмотуватися.


Як примусово встановити висоту огляду? Я спробував setMinimumHeight (0); перед приховуванням, але, здається, не працює. Я встановив його для GONE, але простір комірки все ще залишається позаду.
Моріс

Висота та ширина є параметрами макета, тому вам потрібно встановити об’єкт LayoutParameters для подання з новою шириною / висотою. Дивіться цю відповідь SO: stackoverflow.com/a/2767142/59058 . В основному, ширина, висота та поля - це властивості, які дійсно застосовуються до контейнера подання, а не до самого перегляду, тому для їх визначення ви використовуєте об’єкт LayoutParameter, пов’язаний з батьками.
Йоні Самлан

Я не думаю, що це працює для заголовка, я отримав значення null для заголовка, який був прикріплений і викликався getLayoutParams () для.
Вадим Перетокін

5

у моєму випадку addFooterView / removeFooterView () спричиняє деякі артефакти. І я знайшов інше рішення. Я використовував FrameLayout як FooterView. І коли я хочу додати нижній колонтитул, я зателефонував mFrameFooter.addView (myFooter); та mFrameFooter.removeAllViews (); для видалення.

FrameLayout frameLayout = new FrameLayout(this);
listView.addFooterView(frameLayout);
......
......
//For adding footerView
frameLayout.removeAllViews();
frameLayout.addView(mFooterView);
//For hide FooterView
frameLayout.removeAllViews();

Працює як оберіг. Це повинна бути прийнята відповідь :)
Король Мас


4

Добре працює в моєму проекті:

1.Додайте спочатку колонтитул

mListView.addFooterView(mFooterView); mListView.setAdapter(mAdapter);

2. встановити видимість

mFooterView.setVisibility(View.GONE); mFooterView.setPadding(0, 0, 0, 0);

3. встановіть невидимість

mFooterView.setVisibility(View.GONE); mFooterView.setPadding(0, -1*mFooterView.getHeight(), 0, 0);


2

Як зазначив @YoniSamlan, цього можна досягти простим способом. Ви повинні вказати

android:layout_height="wrap_content" 

у групі перегляду, яка містить кнопку "Завантажити більше". Не обов’язково повинен бути FrameLayout, див. Нижче простий робочий приклад, який використовує LinearLayout.

На обох зображеннях відображається екран, який прокручується донизу. Перший має видимий колонтитул, який обертається навколо кнопки "завантажити більше". Друге зображення показує, що нижній колонтитул згортається, якщо ви встановите для видимості кнопки GONE.

Ви можете знову показати нижній колонтитул (всередині якогось зворотного виклику), змінивши видимість:

loadMore.setVisibility(View.VISIBLE);  // set to View.GONE to hide it again

listView з видимим колонтитулом listView, коли нижній колонтитул відсутній

Виконайте ініціалізацію listView як зазвичай

    // Find View, set empty View if needed
    mListView = (ListView) root.findViewById(R.id.reservations_search_results);
    mListView.setEmptyView(root.findViewById(R.id.search_reservations_list_empty));

    // Instantiate footerView using a LayoutInflater and add to listView
    footerView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
            .inflate(R.layout.load_more_footer_view, null, false);
    // additionally, find the "load more button" inside the footer view
    loadMore = footerView.findViewById(R.id.load_more);
    loadMore.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            fetchData();
        }
    });

    // add footer view to the list
    mListView.addFooterView(footerView);

    // after we're done setting the footerView, we can setAdapter
    adapter = new ReservationsArrayAdapter(getActivity(), R.layout.list_item_reservations_search, reservationsList);
    mListView.setAdapter(adapter);

load_more_footer_view.xml

<?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="wrap_content">

<Button
    android:id="@+id/load_more"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="9dp"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@drawable/transparent_white_border"
    android:textColor="@android:color/white"
    android:text="@string/LOAD_MORE"/>


2

Це повинна бути помилка Android.

Вам не потрібно динамічно видаляти або додавати подання нижнього колонтитула. Вам просто потрібно створити невизначену висоту батьківського макета (або надути його з файлу xml, або створити програмно), а потім додати свій вигляд, який ви хочете приховати або показати в ньому.

І ви можете встановити для подання, але НЕ батьківського макета, значення VISIBLE або GONE або щось інше. Це працює для мене.


0

Використовується

footer.removeAllViews();

Це не видаляє нижній колонтитул, а змиває дітей. Вам знову доведеться заселяти дітей. Може перевірити

footer.getChildCount()<2

0

Я також виявив, що можливий виклик onContentChanged()(якщо ви використовуєте ListActivity) для примусового відтворення, ListViewякщо мені потрібно додати HeaderViewдо них після setAdapter()дзвінка, але це дуже потворний хак.


0

Я створив ListView, який це обробляє. Він також має можливість використовувати EndlessScrollListener, який я створив, для обробки нескінченних переглядів списків, який завантажує дані, поки не буде більше даних для завантаження.

Ви можете переглянути ці класи тут:

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/helper/ListViewWithLoadingIndicatorHelper.java - Помічник функції без розширення з SimpleListViewWithLoadingIndicator.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/listener/EndlessScrollListener.java - прослуховувач, який запускає завантаження даних, коли користувач ось-ось дійде до кінця ListView.

https://github.com/CyberEagle/OpenProjects/blob/master/android-projects/widgets/src/main/java/br/com/cybereagle/androidwidgets/view/SimpleListViewWithLoadingIndicator.java - The EndlessListView. Ви можете використовувати цей клас безпосередньо або продовжити з нього.


0

У мене є невеликий хакерський спосіб вирішити цю проблему скрізь. Помістіть перегляд списку та нижній колонтитул (лише допоміжний макет) у батьківський макет, як LinnearLayout, пам’ятайте, що нижній колонтитул нижче списку.

Контролер цього вигляду нижнього колонтитула зник, а видимість подібна до номінального. І готово!


0

спочатку я додаю свій нижній колонтитул до списку, наприклад

listView.addFooterView(Utils.b);

Потім при натисканні кнопки я видаляю вигляд,

listView.removeFooterView(Utils.b);

Я додаю нижній колонтитул щоразу, коли потрапляю в асинхронний, і тому це не дублюється запис. Я міг також перевірити кількість, і тому це подобається,

if(listView.getFooterViewsCount() > 0){//if footer is added already do something}

-1

Коли ви хочете видалити нижній колонтитул, ListViewпросто зателефонуйте

listView.addFooterView(new View(yourContext)); 

Він додасть фіктивний порожній вигляд, який не зарезервує місця


1
в документації сказано: "Якщо addFooterView викликається більше одного разу, подання відображатимуться в тому порядку, в якому вони були додані."
max4ever
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.