解决ListView列表setEmptyView无效问题及源码解析
时间: 2023-12-18 15:02:57 浏览: 122
Android软件开发之ListView 详解源码
5星 · 资源好评率100%
ListView的setEmptyView方法是用来设置列表为空时显示的View,但是有时候我们在使用该方法时发现并没有生效,可能是以下几个原因:
1. 没有给ListView设置Adapter,因为只有当Adapter没有数据时才会显示EmptyView。
2. 在设置EmptyView之前已经给ListView设置了数据源,需要在设置EmptyView之前将数据源清空。
3. 在设置EmptyView之前需要先inflate出EmptyView的布局,并将其添加到ListView的父布局中。
以下是一个setEmptyView无效的例子:
```java
ListView listView = findViewById(R.id.list_view);
View emptyView = findViewById(R.id.empty_view);
listView.setEmptyView(emptyView);
String[] data = {"item1", "item2", "item3"};
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data);
listView.setAdapter(adapter);
```
上述代码中,设置了EmptyView,但是并没有生效,因为在设置EmptyView之前已经给ListView设置了数据源,需要将数据源清空,即在setAdapter之前添加如下代码:
```java
listView.setAdapter(null);
```
另外,还需要注意,EmptyView需要先inflate出来并添加到ListView的父布局中,例如:
```java
View emptyView = LayoutInflater.from(this).inflate(R.layout.empty_view, (ViewGroup) listView.getParent(), false);
```
至于ListView的源码实现,可以参考以下几个方法:
1. setEmptyView方法:
```java
public void setEmptyView(View emptyView) {
mEmptyView = emptyView;
final T adapter = mAdapter;
final boolean empty = ((adapter == null) || adapter.isEmpty());
updateEmptyStatus(empty);
}
private void updateEmptyStatus(boolean empty) {
if (isInFilterMode()) {
empty = false;
}
if (empty) {
if (mEmptyView != null) {
mEmptyView.setVisibility(View.VISIBLE);
setVisibility(View.GONE);
} else {
// If the caller just removed our empty view, make sure the list view is visible
setVisibility(View.VISIBLE);
}
// We are now GONE, so pending layouts will not be dispatched.
// Force one here to ensure that the state of the list matches
// the state of the adapter.
if (mDataChanged) {
this.onLayout(false, getLeft(), getTop(), getRight(), getBottom());
}
} else {
if (mEmptyView != null) {
mEmptyView.setVisibility(View.GONE);
}
setVisibility(View.VISIBLE);
}
}
```
2. setAdapter方法:
```java
public void setAdapter(ListAdapter adapter) {
if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
resetList();
}
mAdapter = adapter;
if (mAdapter != null) {
mOldSelectedPosition = INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
mItemCount = mAdapter.getCount();
mDataChanged = true;
// Detect the case where a cursor that was previously invalidated has
// been repopulated with new data.
mHasStableIds = mAdapter.hasStableIds();
if (mChoiceMode != CHOICE_MODE_NONE && mAdapter.hasStableIds()) {
mChoiceMode = CHOICE_MODE_SINGLE;
if (mCheckStates == null) {
mCheckStates = new SparseBooleanArray();
}
if (mCheckedIdStates == null) {
mCheckedIdStates = new LongSparseArray<Boolean>();
}
}
if (!mPopupHidden) {
// Show the popup if we have one
if (mAdapter.getCount() > 0) {
showPopup();
}
}
} else {
mItemCount = 0;
mDataChanged = false;
mHasStableIds = false;
mOldSelectedPosition = INVALID_POSITION;
mOldSelectedRowId = INVALID_ROW_ID;
mChoiceMode = CHOICE_MODE_NONE;
mCheckStates.clear();
mCheckedIdStates.clear();
// Hide the currently visible popup
dismissPopup();
}
if (mFilter != null) {
mAdapter.getFilter().filter(mFilter);
}
requestLayout();
}
```
阅读全文