SwipeRefreshLayout может содержать только один прямой дочерний элемент

Я добавил «тянуть для обновления» в свой listView, я также хотел добавить пустое представление, когда список пуст — теперь я получил эту ошибку. Как я могу заставить это работать? если я позиционирую представление за пределами swipeRefresh, а затем добавляю его как emptyView, оно будет работать. Итак, как мне это сделать с внешним файлом xml ..?

XML-код:

        <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >


        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:clipToPadding="false"
            android:paddingBottom="@dimen/inbox_vertical_margin" ></ListView>


</android.support.v4.widget.SwipeRefreshLayout>

onCreateView:

View rootView = inflater.inflate(R.layout.fragment_inbox, container,
        false);

View empty = inflater.inflate(R.layout.empty_message_list, container,
        false);
ListView mListView = (ListView) rootView
        .findViewById(android.R.id.list);
((ViewGroup) mListView.getParent()).addView(empty);
TextView textViewToChange = (TextView) empty
        .findViewById(R.id.welcomeMessage);

textViewToChange.setText("YO "
        + ParseUser.getCurrentUser().getString(
                ParseConstants.KEY_PRESENTING_USERNAME)
        + "!  bad news.. :(");
mListView.setEmptyView(empty);

mSwipeRefreshLayout = (SwipeRefreshLayout) rootView
        .findViewById(R.id.swipeRefreshLayout);
mSwipeRefreshLayout.setOnRefreshListener(mOnRefreshListener);
mSwipeRefreshLayout.setColorScheme(R.color.swipeRefresh1,
        R.color.swipeRefresh2, R.color.swipeRefresh3,
        R.color.swipeRefresh4);

return rootView;

person Yevgeni    schedule 23.05.2014    source источник
comment
я столкнулся с той же проблемой и обнаружил, что, хотя вы используете только одно представление списка, которое является только одним дочерним элементом, и это нормально, но вы можете скрывать его видимость, это то, что я сделал ошибку на своем конце   -  person Syed Raza Mehdi    schedule 30.04.2015


Ответы (2)


SwipeRefreshLayout должен быть родителем в файле XML.

Вы можете использовать FrameLayout в качестве дочернего элемента SwipeRefreshLayout. ListView и TextView (или любое другое пустое представление состояния) могут быть дочерними представлениями FrameLayout.

person LordRaydenMK    schedule 23.05.2014
comment
Есть ли способ установить SwipeRefreshLayout внутри другого макета как дочерний? - person Vinil Chandran; 07.01.2016
comment
@VinilChandran уверен. Вы можете использовать его, например. внутри CoordinatorLayout. Единственным ограничением является то, что SwipeRefreshLayout может иметь только одного дочернего элемента, представление, которое обновляется. - person LordRaydenMK; 07.01.2016
comment
Разве вы не сталкиваетесь с ошибкой, когда ListView не может прокручиваться вверх, если вы делаете это так? Я испытал это и читал об этом. innodroid.com/blog/post/recycler-empty-swipe-refresh - person Varvara Kalinina; 25.04.2017

Мне нужно было реализовать ту же функцию «потяните, чтобы обновить» в моих приложениях. Альтернативный (и довольно простой) способ реализации «пустого представления» — использовать представления верхнего или нижнего колонтитула ListView.

Сначала вы создаете «empty_view.xml», содержащий макет пустого представления. Затем в методе onCreate() вашего хостинга сделайте что-то вроде:

View headerView = LayoutInflater.from(this).inflate(R.layout.empty_view, myListView, false);
myListView.addHeaderView(headerView);
myListView.setAdapter(adapter);

// populate your ListView here
// ......

// now check the number of items and remove the empty view if needed
if (number_of_items > 1) {
  myListView.removeHeaderView(headerView);
}
adapter.notifyDataSetChanged();

В приведенном выше коде myListView — это объект ListView, а adapter — его адаптер.

Это полезно и в других ситуациях. Например, предположим, что данные списка считываются из веб-службы и загружаются медленно, тогда можно поместить ProgressBar в представление и установить его в качестве представления заголовка ListView, чтобы у пользователя была некоторая визуальная индикация.

person macelee    schedule 26.02.2016