Another option that works nicely in case that your empty view doesn't need any interaction. For example, it is a simple textview saying "No data in here."
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/emptyView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="visible"
android:layout_centerInParent="true"
android:text="@string/no_earnable_available"
android:textSize="18dp"
android:textColor="@color/black"
android:background="@color/white"
/>
<some.app.RecyclerViewSwipeToRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="4dp"
android:background="@android:color/transparent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
/>
</some.app.RecyclerViewSwipeToRefreshLayout>
</RelativeLayout>
This puts the empty view behind the SwipeToRefreshLayout which is transparent and which contains also a transparent RecyclerView.
Then, in the code, in the place where you add the items to the recycler view adapter, you check if the adapter is empty, and if so you set the visibility of the empty view to "visible". And vice versa.
The trick is that the view is behind the transparent recycler view, which means that the recycler view and his parent, the SwipeToRefreshLayout, will handle the scroll when there are no items in the recycler. The empty view behind won't even be touched so the touch event will be consumed by the SwipeTorefreshLayout.
The custom RecyclerSwipeTorefreshLayout should handle the canChildScrollUp method in the following way
@Override
public boolean canChildScrollUp() {
if (recycler == null) throw new IllegalArgumentException("recycler not set!");
else if (recycler.getAdapter().getItemCount() == 0){ // this check could be done in a more optimised way by setting a flag from the same place where you change the visibility of the empty view
return super.canChildScrollUp();
} else {
RecyclerView.LayoutManager layoutManager = recycler.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
return ((LinearLayoutManager) recycler.getLayoutManager()).findFirstVisibleItemPosition() != 0 ||
(((LinearLayoutManager) recycler.getLayoutManager()).findFirstVisibleItemPosition() == 0
&& recycler.getChildAt(0) != null && recycler.getChildAt(0).getY() < 0);
//...
This will do the trick.
UPDATE:
Of course, the recycler view doesn't have to be transparent all the time. You can update the transparency to be active only when the adapter is empty.
Cheers!
FrameLayout
. – Spina