優雅的解決SwipeRefreshLayout和ListView的EmptyView共存衝突的問題(全網獨創)
阿新 • • 發佈:2019-01-29
故事背景
自從Android Material Design出來之後,以其優雅酷炫的效果深受廣大使用者的喜愛,我個人也非常喜歡其漂亮的介面,特別是SwipeRefreshLayout,呵呵看臉的世界ing
言歸正傳最近有個專案需要用到SwipeRefreshLayout巢狀一個listView,該listview不需要上拉載入,就是隻需要簡單的下拉重新整理即可,於是二話不說,直接SwipeRefreshLayout巢狀ListView,嗯,效果完美,佈局程式碼如下
但是考慮到當listview沒有資料的話應該顯示一個提示,比如“暫無資料,下拉重新整理”之類的提示,於是把佈局改成下面這樣:<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipe_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white"/> </android.support.v4.widget.SwipeRefreshLayout>
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipe_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white"/> <include layout="@layout/empty_layout"/> </android.support.v4.widget.SwipeRefreshLayout>
empty_layout.xml
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/empty_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:text="@string/no_content_refresh"/>
然後java程式碼中為ListView設定一下EmptyView,編譯執行,當listview無資料的時候,發現設定無效!!!
網上查詢資料說是SwipeRefreshLayout只能有一個子View,於是按照網上方法改成下面這樣:
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"/>
<include layout="@layout/empty_layout"/>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
更大的問題來了當SwipeRefreshLayout只有ListView一個子view的時候是沒有任何問題的,但如果不是一個子view就會出現問題了,向上滑動ListView一切正常,向下滑動的時候就會出現還沒有滑倒ListView頂部就觸發下拉重新整理的動作了。加了empty_layout之後listview根本無法下拉,每次下拉都是觸發SwipeRefreshLayout的下拉方法。
於是參考了各種方案,如下
重寫SwipeRefreshLayout http://www.eoeandroid.com/forum.php?mod=viewthread&tid=914273
設定listview的setOnScrollListener https://www.2cto.com/kf/201702/601860.html
以及設定onTouchListener
mListView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
Log.d("Measure", "listview.getListPaddingTop():"+mListView.getListPaddingTop()+
" listview.getTop():"+mListView.getTop()+"listview.getChildAt(0).getTop():"+mListView.getChildAt(0).getTop());
if (mListView.getFirstVisiblePosition() == 0 &&
mListView.getChildAt(0).getTop() >= mListView.getListPaddingTop()) {
mRefreshLayout.setEnabled(true);
Log.d("TAG", "reach top!!!");
}else mRefreshLayout.setEnabled(false);
}
return false;
}
});
發現設定onTouchListener和setOnScrollListener 效果差不多,listview確實能夠下滑了,但是有一個小bug,好像SwipeRefreshLayout 下拉的時候有點不靈光,有時候需要下拉兩三次才能夠觸發下拉重新整理,log一直輸出
Got ACTION_MOVE event but don't have an active pointer id
然後效果類似下面這樣:
無法觸發下拉,嘗試了兩三次之後,又正常了,這個效果還是不太滿意,so,受到網友的啟發,得到了下面的方案:
終極解決方案:
其實只需要把佈局稍微改變一下即可完美解決,修改之後的佈局如下:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/empty_layout"/>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"/>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
其他的都不用變,這個佈局非常巧妙的解決了以上難題,應該是全網最優雅的一種方式了,不敢獨享,遂熬夜拿出來跟大家一起共享~~~~~ 最後放上一張效果圖