ListView如何动态显示与隐藏headerview,footerview

前言

很多情况我们需要用到ListView的addHeaderView(View v)以及addFooterView(View v)以满足我们的需求。比如我们项目中的情况:ListView上面需要显示一个循环的广告轮播图,我们是使用了自定义的一个控件Loopbanner来显示轮播图,使用的listview.addHeaderView(loopbanner);来添加到ListView的头部这样就可以不用嵌套ScrollView。但是又有一个新的需求,就是假如广告图片没有数据的时候将广告位隐藏掉。本来我想的挺开心,直接loopbanner.setVisibility(View.GONE);不久可以了嘛,但是试了一下,loopbanner倒是隐藏掉了,但是还是它占据一定的空间还是保留着,空荡荡的一片

找方案

在网上找了一个方法就是先隐藏然后,设置padding,
隐藏时

loopBanner.setVisibility(View.VISIBLE);
this.loopBanner.setPadding(0, -loopBanner.getHeight(), 0, 0)

需要显示时

 loopBanner.setVisibility(View.GONE);
 this.loopBanner.setPadding(0, 0, 0, 0);

这种方案,确实有了效果,去除了空荡荡的一篇片,但是在我们的项目中出了状况,就是用户先下拉刷新几次,然后上滑,就忽然崩溃,报的错误是:

Process: com.test, PID: 20067
    java.lang.NullPointerException: Attempt to invoke virtual method 'com.test.base.adapter.ViewHolder com.test.base.adapter.ViewHolder.setViewGone(int)' on a null object reference

    at com.test.adapter.CPostAdapter.convert(CPostAdapter.java:63)
    at com.test.adapter.CPostAdapter.convert(CPostAdapter.java:33)
    at com.test.base.adapter.UniversalAdapter.getView(UniversalAdapter.java:53)
    at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:220)
    at android.widget.AbsListView.obtainView(AbsListView.java:2346)
    at android.widget.ListView.makeAndAddView(ListView.java:1876)
    at android.widget.ListView.fillDown(ListView.java:702)
    at android.widget.ListView.fillGap(ListView.java:666)
    at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5106)
    at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3463)
    at android.widget.AbsListView.onTouchMove(AbsListView.java:3878)
    at android.widget.AbsListView.onTouchEvent(AbsListView.java:3691)
    at android.view.View.dispatchTouchEvent(View.java:9306)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2548)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2241)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at cn.bingoogolapple.refreshlayout.BGARefreshLayout.dispatchTouchEvent(BGARefreshLayout.java:425)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2554)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2255)
    at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2403)
    at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2820)
    at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2364)
    at android.view.View.dispatchPointerEvent(View.java:9526)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4255)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4121)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3662)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3715)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3681)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3807)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3689)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3864)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java

这个错误挺奇怪的,holder报空,以前应该从来没遇到过,我们的baseAdapter也是经多多次检验与改良应该没什么问题,但是有一点可以确定,就是我改了隐藏headerView之后才出现的这个错误的,所以我就又寻找了一个方案

最终方案

就是给LoopBanner外加了一层FrameLayout,使用frameLayout.removeAllViews和addView确定显示以及不显示,目前还未遇到holder报空的情况

FrameLayout frameLayout = new FrameLayout(this);
listView.addFooterView(frameLayout);
......
......
//For adding footerView
frameLayout.removeAllViews();
frameLayout.addView(mFooterView);
//For hide FooterView
frameLayout.removeAllViews();

你可能感兴趣的:(Android)