Скрыть нижний колонтитул в ListView?

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

loadingView.setVisibility(View.GONE);

К сожалению, хотя это скрывает представление, оно оставляет для него пространство. То есть В итоге я получил большое пустое место, где раньше было сообщение "Загрузка". Как я могу правильно скрыть это представление?

Я не могу использовать removeFooterView(), потому что мне может потребоваться показать его снова, и в этом случае я не могу снова вызвать addFooterView(), потому что адаптер уже установлен на ListView, и вы не можете вызовите addHeaderView()/addFooterView() после установки адаптера.

Ответ 1

Кажется, вам разрешено вызывать addHeaderView()/addFooterView() после setAdapter(), пока вы вызываете один из этих методов хотя бы один раз до. Это довольно плохое дизайнерское решение от Google, поэтому я написал вопрос. Объедините это с removeFooterView(), и у вас есть мое решение.

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

Ответ 2

Попробуйте установить высоту нижнего колонтитула до 0px или 1px, прежде чем скрывать ее. В качестве альтернативы, оберните представление нижнего колонтитула в wrap_content height FrameLayout и скройте/покажите внутренний вид, оставив FrameLayout видимым; высота должна быть надлежащим образом завершена.

Ответ 3

в моем случае addFooterView/removeFooterView() вызывает некоторые артефакты. И я нашел другое решение. Я использовал FrameLayout как FooterView. И когда я хочу добавить Footer, я назвал 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

Библиотека Droid-Fu имеет класс, предназначенный для отображения нижнего колонтитула загрузки и скрыть: ListAdapterWithProgress.

Ответ 5

Хорошо работает в моем проекте:

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);

Ответ 6

Как отметил @YoniSamlan, это может быть достигнуто простым способом. Вы должны указать

android:layout_height="wrap_content" 

в группе ViewGroup, содержащей кнопку "Загрузить еще". Не обязательно быть FrameLayout, см. Ниже пример простого примера работы, который использует LinearLayout.

Оба изображения показывают экран, который прокручивается до конца. Первый имеет видимый нижний колонтитул, который обтекает кнопку "загрузить больше". Второе изображение показывает, что нижний колонтитул рушится, если вы установите видимость кнопок на GONE.

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

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

listView with visible footerlistView with footer gone

Выполнить инициализацию 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"/>

Ответ 7

Это должно быть ошибка Android.

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

И вы можете установить представление, но НЕ родительский макет, в VISIBLE или GONE или что-то еще. Это работает для меня.

Ответ 8

Если вы хотите удалить нижний колонтитул в ListView, просто вызовите

listView.addFooterView(new View(yourContext)); 

Он добавит пустой пустынный вид, который не зарезервирует какое-либо пространство

Ответ 9

Используется

footer.removeAllViews();

Это не удаляет нижний колонтитул, но очищает детей. Вам снова придется пересаживать детей. Можно проверить на

footer.getChildCount()<2

Ответ 10

Я также обнаружил, что возможен вызов onContentChanged() (если вы используете ListActivity), чтобы заставить recreate ListView, если мне нужно добавить HeaderView к ним после вызова setAdapter(), но это очень уродливое взломать.

Ответ 11

Я создал 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. Вы можете использовать этот класс напрямую или от него.

Ответ 12

У меня есть небольшой способ взлома решения этой проблемы везде. Поместите представление listview и footer (только макет) в родительском макете, таком как LinnearLayout, помните, что footerview ниже listview.

Контроллер этого нижнего колонтитула не отображается и видимость, как вид номенклатуры. И сделано!

Ответ 13

Сначала я добавляю свой нижний колонтитул в список, как этот

listView.addFooterView(Utils.b);

Затем при нажатии кнопки я удаляю представление,

listView.removeFooterView(Utils.b);

Я добавляю нижний колонтитул каждый раз, когда я нахожусь в асинхронном режиме, а theus не дублирует запись. Я мог бы также проверить счетчик, и так вот так:

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