0%

listview添加footerview不生效

问题

使用listview添加footerview,始终显示不出来。

上网一查,Android-4.4之前添加footerview一定要在setAdapter之前,换句话说,addFooterView之后需要重新setAdapter才能生效
之前的代码是这样的:

1
2
3
if (mListView.getFooterViewsCount() == 0) {
mListView.addFooterView(createMoreCityView());
}

改成如下即可

1
2
3
4
5
6
if (mListView.getFooterViewsCount() == 0) {
mListView.addFooterView(createMoreCityView());
if (SystemUtils.isBelowKitkat()) {
mListView.setAdapter(mCityAdapter);
}
}

原因

在Android 4.4之前,ListView添加footerview大致代码是这样的(下方是android 4.2.2代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* Add a fixed view to appear at the bottom of the list. If addFooterView is
* called more than once, the views will appear in the order they were
* added. Views added using this call can take focus if they want.
* <p>
* NOTE: Call this before calling setAdapter. This is so ListView can wrap
* the supplied cursor with one that will also account for header and footer
* views.
*
* @param v The view to add.
* @param data Data to associate with this view
* @param isSelectable true if the footer view can be selected
*/
public void addFooterView(View v, Object data, boolean isSelectable) {
// NOTE: do not enforce the adapter being null here, since unlike in
// addHeaderView, it was never enforced here, and so existing apps are
// relying on being able to add a footer and then calling setAdapter to
// force creation of the HeaderViewListAdapter wrapper
FixedViewInfo info = new FixedViewInfo();
info.view = v;
info.data = data;
info.isSelectable = isSelectable;
mFooterViewInfos.add(info);
// in the case of re-adding a footer view, or adding one later on,
// we need to notify the observer
if (mAdapter != null && mDataSetObserver != null) {
mDataSetObserver.onChanged();
}
}

Note明确提示需要在setAdater之前添加footerview,在setAdater之后,会重新生成一个HeaderViewListAdapter来展示footerview,否则不会生效。

而在Android 4.4之后,ListView添加footerview代码大致为(下方为android 7.0.0代码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* Add a fixed view to appear at the bottom of the list. If addFooterView is
* called more than once, the views will appear in the order they were
* added. Views added using this call can take focus if they want.
* <p>
* Note: When first introduced, this method could only be called before
* setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
* {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
* called at any time. If the ListView's adapter does not extend
* {@link HeaderViewListAdapter}, it will be wrapped with a supporting
* instance of {@link WrapperListAdapter}.
*
* @param v The view to add.
* @param data Data to associate with this view
* @param isSelectable true if the footer view can be selected
*/
public void addFooterView(View v, Object data, boolean isSelectable) {
final FixedViewInfo info = new FixedViewInfo();
info.view = v;
info.data = data;
info.isSelectable = isSelectable;
mFooterViewInfos.add(info);
mAreAllItemsSelectable &= isSelectable;
// Wrap the adapter if it wasn't already wrapped.
if (mAdapter != null) {
if (!(mAdapter instanceof HeaderViewListAdapter)) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
// In the case of re-adding a footer view, or adding one later on,
// we need to notify the observer.
if (mDataSetObserver != null) {
mDataSetObserver.onChanged();
}
}
}

就不会有这个问题了。

结论

Android 4.4之前,addFooterView之后需要(重新)设置Adapter才能生效
Android 4.4及以后,addFooterView可以在任意地方调用