adapterview 设置多种emptyview

    以前一直不知道emptyview的存在,觉得像qq那些 无数据时显示的效果很好,想来想去找不到办法实现那样的效果。后来在一个群问时,有人回答 adapterview 有个方法setEmptyView(),就可以设置无数据的提示效果.才知道实现这个效果很简单大哭大哭

    后来项目中需要添加无数据时的提示效果, 大多是使用动态加载。使用动态添加在初始化时加入进去就可以满足一般的情况了(qq的消息列表好像这样就可以了)。  TextView textView = new TextView(getBaseContext());

<span style="font-size:18px;"> textView.setText("当前分类无可配送门店,请更换其他分类");
 textView.setGravity(Gravity.CENTER);
 textView.setVisibility(View.GONE);
 textView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
 LayoutParams.FILL_PARENT));
((ViewGroup) listview.getParent()).addView(<span style="font-family: Arial, Helvetica, sans-serif;">textView</span><span style="font-family: Arial, Helvetica, sans-serif;">);</span><span style="font-family: Arial, Helvetica, sans-serif;">	</span>
listview.setEmptyView(no_classfication_tv);</span>
 

    写到这突然想到了,以前反编译一些app,像58、赶集 都是将网络错误、无数据提示的布局include到当前activity的布局里,这就是接下来说要使用到的方式。

    首先说遇到的问题吧,动态加载只在初始化时是没有问题的,因为只将emptyview添加了一次到listview的parent里,项目中的所遇到的情况是在数据请求返回后根据结果去设置不同的emptyview,于是我把上面那段代码 放到每次请求后调用,这时问题就来了,每次执行那段代码都会将一个emptyview 添加进去。

    看了下addView()的代码

<span style="font-size:18px;"> /**
     * Adds a child view. If no layout parameters are already set on the child, the
     * default parameters for this ViewGroup are set on the child.
     *
     * @param child the child view to add
     *
     * @see #generateDefaultLayoutParams()
     */
    public void addView(View child) {
        addView(child, -1);
    }</span>

    后面 还有就不看了.所以这种方法就不太好,如果有多种emptyview,处理起来就麻烦了。

   还有一种实现形式,就是在布局里,include layout 然后设置显示属性为gone,为什么要这么设,之后再说,这样不用每次都动态添加到adapterview的父布局里了,

    代码里只需要调用adapterview.setEmptyView(View) 就可以了,我在当前adapterview的父布局里加了两个emptyview,然后根据数据请求结果带调用   adapterview.setEmptyView(View) .问题又来了,如果设置了两种emptyview后,有一种会一直显示,这是为什么呢?

    接下来就要看adapterview.setEmptyView(View)的代码了

<span style="font-size:18px;">   /**
      * Sets the view to show if the adapter is empty
      */
     @android.view.RemotableViewMethod
     public void setEmptyView(View emptyView) {
         mEmptyView = emptyView;

        final T adapter = getAdapter();
        final boolean empty = ((adapter == null) || adapter.isEmpty());
        updateEmptyStatus(empty);
    }</span>
    我们看到该方法最后调用的是
<span style="font-size:18px;">     updateEmptyStatus(empty);</span>
    传入的是个boolean值 ,adapter为null或者为空时 为true

    接着看 

<span style="font-size:18px;">   updateEmptyStatus(empty);</span>

<span style="font-size:18px;">    /**
     * Update the status of the list based on the empty parameter.  If empty is true and
     * we have an empty view, display it.  In all the other cases, make sure that the listview
     * is VISIBLE and that the empty view is GONE (if it's not null).
     */
    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 make sure that the state of the list matches
            // the state of the adapter.
            if (mDataChanged) {           
                this.onLayout(false, mLeft, mTop, mRight, mBottom); 
            }
        } else {
            if (mEmptyView != null) mEmptyView.setVisibility(View.GONE);
            setVisibility(View.VISIBLE);
        }
    }</span>

<span style="font-size:18px;">    boolean isInFilterMode() {
        return false;
    }</span>
    第一个if 不用管 返回的是false 所以不会改变empty的值

    下面就是对empty的判断

     emptyview不为null 也就是我们设置了emptyview 而且此时没有数据,emptyview 会设置为可见,如果不为空且存在,就设置为gone.这就解释了为什么一开始要设置为gone的原因,emptyview的显示和隐藏是adapter来控制的。知道了这个我所遇到的问题就好解决了,因为设置了两次emptyview,但是每次adapter只会对最后一次设置的emptyview控制显示、隐藏,所以只需要每次在设置emptyview前,将所有emptyview设置为gone,然后设置emptyview,这样就会每次只显示我们所要显示的emptyview了。

   看到stackoverflow 的 一个关于使用两种emptyview的答案

 If I got error or got no data from database or server, I set visibility of ProgressBar to Gone and change visibility of TextView to Visible. And then set TextView as empty view of my ListView.

并不需要每次手动设置emptyview为Visible,adapterview会根据当前状态设置emptyview是显示还是隐藏,我们只需将他们都设置为gone即可.


如果遇到要使用多种emptyview的情况,可能使用第二种的方法会很好,但是只有一种emptyview而且项目中列表无数据提示的样式是一样的情况下,将设置emptyview的代码写成公共类就方便多了,或者每次动态添加前先将adapterview的parent中的其他view移除,然后再添加?这种还没试过。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值