SwipeRefreshLayout在空的RecyclerView上被隐藏了

10
我有一个包含 SwipeRefreshLayout 和 RecyclerView 的 Fragment。
当提交该 Fragment 时,它会开始与服务器通信以检索一些数据并填充 CustomAdapter 来为 RecyclerView 提供服务。
用户可以通过向下滑动或在 ActionBar 上按下按钮来刷新内容。在后一种情况下,我手动调用 swipeRefreshLayout.setRefreshing(true)。到目前为止都没有问题。
问题出现在我在 RecyclerView 的第一次加载期间(onStart())手动调用了刷新状态。进度指示器没有显示出来,我认为是因为 RecyclerView 仍然为空,因为它需要几秒钟来检索所有数据...
以下是一些代码。
Fragment 代码:
public class MyFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

        View mView = inflater.inflate(R.layout.fragment_stop, container, false);
        mRecyclerView = (RecyclerView) mView.findViewById(R.id.recyclerView1);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(),
             DividerItemDecoration.VERTICAL_LIST));
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

       //SwipeRefreshLayout retrieved and  configured
       swipeLayout = (SwipeRefreshLayout) mView.findViewById(R.id.swipe_container);
       swipeLayout.setOnRefreshListener(this);
       swipeLayout.setColorSchemeResources(
            R.color.primaryColor,
            R.color.cyan_500,
            R.color.light_green_500,
            R.color.amber_500);

        return mView;


     }

    ...
    @Override
        public void onStart() {
            super.onStart();
            executeSchedule(); //First execution and data loading.
        }
        ...

    @Override
    public void onRefresh() {
        executeSchedule();
    }
    ...
    public void executeSchedule() {
        new Schedule().execute();
    }



    private class Schedule extends AsyncTask<Void, Void, Void> {

        ...
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if(!swipeLayout.isRefreshing()) {
                swipeLayout.setRefreshing(true); //set refresh state
            }
        }

        @Override
        protected Void doInBackground(Void... params) {
        ...
        }

        @Override
        protected void onPostExecute(Void result) {
            adap = new CustomAdapter(getActivity(), ...);
            mRecyclerView.setAdapter(adap);
            swipeLayout.setRefreshing(false);
        }

}

XML 代码:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/section_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <android.support.v4.widget.SwipeRefreshLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/swipe_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="4dp"
                android:paddingRight="4dp"
                android:paddingBottom="2dp"
                android:layout_marginTop="5dp"
                android:divider="#e0e0e0"
                tools:context=".MyFragment" />

        </android.support.v4.widget.SwipeRefreshLayout>
    </RelativeLayout>
</FrameLayout>
什么是处理这种情况最好的做法? 是添加第二个虚拟的SwipeRefreshLayout吗?还是立即强制使用一个空的适配器?
3个回答

17

我在使用一个空的recycler时,SwipeRefreshLayout无法正常工作,因此我创建了一个非常简单的空适配器。

public class EmptyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }
}

你如何使用它? - Rahul Hawge
3
mRecyclerView.setAdapter(new EmptyAdapter());这行代码的意思是将一个名为 "EmptyAdapter" 的空适配器设置给变量 "mRecyclerView"。 - Mutahar Maqbool

7
我只是在SwipeRefreshLayout中用RelativeLayout包装了RecyclerView,问题就解决了。
<android.support.v4.widget.SwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swipeContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

</android.support.v7.widget.RecyclerView>
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>

虽然这段代码可能回答了问题,但是提供关于为什么和/或如何回答问题的额外上下文会提高它的长期价值。 - Jack
谢谢!这个解决方案对我很有用(RecyclerView 的第一个单元格被隐藏了)。 - Cao Mạnh Quang

0

谢谢。我不知道那个。 毫无疑问,这比调用 setProgressViewOffset() 更好的解决方案。 - Emanuele

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接