SwipeRefreshLayout Hidden Behind ActionBar with Transparent Status Bars
When using a transparent status bar and ActionBar, the SwipeRefreshLayout can sometimes appear hidden behind the ActionBar. This issue arises due to the default behavior of Android’s layout system.
Understanding the Problem
Default Layout Behavior
- Android’s layout system places views in a hierarchy.
- Views higher in the hierarchy can obscure views lower in the hierarchy.
- By default, the ActionBar and status bar are positioned higher in the hierarchy than the SwipeRefreshLayout.
Transparent Status Bar and ActionBar
- When the status bar and ActionBar are transparent, their content becomes visible but their layout positions remain unchanged.
- This can lead to the SwipeRefreshLayout being hidden behind the transparent areas.
Solutions
1. Padding Adjustment
Add padding to the SwipeRefreshLayout to push it below the ActionBar and status bar.
Implementation:
<android.support.v4.widget.SwipeRefreshLayout android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <!-- Content View --> </android.support.v4.widget.SwipeRefreshLayout>
Explanation:
- The `android:padding` attribute adds padding to all sides of the SwipeRefreshLayout.
- Adjust the padding value to create enough space for the ActionBar and status bar.
2. Translucent System UI
Set the status bar and ActionBar to translucent. This will allow views behind them to be visible.
Implementation:
<!-- In the Activity's onCreate() method --> getWindow().setFlags( WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS );
Explanation:
- The `FLAG_LAYOUT_NO_LIMITS` flag allows views to draw behind the system UI.
3. CoordinatorLayout
Use CoordinatorLayout with AppBarLayout to control the layout of the SwipeRefreshLayout.
Implementation:
<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <!-- Toolbar or other elements --> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.SwipeRefreshLayout android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <!-- Content View --> </android.support.v4.widget.SwipeRefreshLayout> </android.support.design.widget.CoordinatorLayout>
Explanation:
- CoordinatorLayout provides flexible layout behavior with dependency injection.
- AppBarLayout is a subclass of LinearLayout specifically designed for use with CoordinatorLayout.
- The `app:layout_behavior=”@string/appbar_scrolling_view_behavior”` attribute tells the SwipeRefreshLayout to scroll behind the AppBarLayout when it is scrolled.
Comparison
Solution | Pros | Cons
|—|—|—|
| Padding Adjustment | Simple implementation | May require trial-and-error for correct padding value |
| Translucent System UI | Consistent appearance | May affect other UI elements |
| CoordinatorLayout | Flexible layout control | Requires using CoordinatorLayout and AppBarLayout |
Code Example
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout 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"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/colorPrimary" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="My App" /> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.v4.widget.SwipeRefreshLayout> </android.support.design.widget.CoordinatorLayout>
Conclusion
By understanding the layout behavior of the SwipeRefreshLayout and the effect of transparent system UI, you can choose the appropriate solution to ensure the SwipeRefreshLayout is correctly displayed and fully functional.