adapterview 设置多种emptyview

来源:互联网 发布:php爬虫视频教程 编辑:程序博客网 时间:2024/05/03 16:59

    以前一直不知道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移除,然后再添加?这种还没试过。






0 0
原创粉丝点击