我有另一个很好的想法。
继承 ListView 并覆盖 setAdapter() 和 setEmptyView()。
setEmptyView 应该只存储用于空视图的视图,并且
setAdapter 应该注册一个 DataSetObserver 来隐藏/显示空视图而不改变列表视图的可见性。您可能希望使用一个 FrameLayout 来保存您的 SwipeToRefreshLayout 和一个空视图(作为兄弟姐妹)。然后,您可以使用重力和布局重力很容易地将空视图定位在顶部/中间/底部等。您也可以使用 RelativeLayout 但我没有尝试过。你会想以某种方式取消注册 dataSetObserver,我相信你可能想在 onDetachFromWindow 中这样做,就像我在下面所做的那样。
public class SwipeToRefreshCompatibleList extends ListView {
private boolean mIsEmpty = false;
private View mEmptyView;
private Adapter mAdapter;
private DataSetObserver mLocalObserver = new DataSetObserver() {
@Override
public void onChanged() {
boolean isEmpty = mAdapter == null || mAdapter.getCount() == 0;
if (mEmptyView != null) {
if (isEmpty != mIsEmpty) {
mEmptyView.setVisibility(isEmpty ? View.VISIBLE : View.GONE);
}
}
mIsEmpty = isEmpty;
}
};
public SwipeToRefreshCompatibleList(Context context) {
super(context);
}
public SwipeToRefreshCompatibleList(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwipeToRefreshCompatibleList(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SwipeToRefreshCompatibleList(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void setAdapter(ListAdapter adapter) {
mAdapter = adapter;
adapter.registerDataSetObserver(mLocalObserver);
super.setAdapter(adapter);
}
@Override
public void setEmptyView(View view) {
mEmptyView = view;
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mLocalObserver);
}
}
}
示例布局文件:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.company.widget.SwipeToRefreshCompatibleList
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/BasicList"
android:divider="@null"
/>
</android.support.v4.widget.SwipeRefreshLayout>
<TextView
android:padding="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center"
android:textSize="18sp"
android:id="@android:id/empty"
/>
</FrameLayout>
虽然这需要更多的代码而不是简单地继承 ListView 并更改 setVisibility 以便它不会将列表设置为 GONE/HIDDEN,但我觉得这不是一个 hack 并且仍然允许用户将列表设置为消失/隐藏,如果他们需要的话。