给ListView设置emptyView

版权声明:本文为博主原创文章,未经博主允许不得转载。

使用ListView和GridView时,当列表为空时,默认是不显示任何内容的,这样对用户非常不友好,这时我们就需要通过setEmptyView(View emptyView)来设置当列表为空时的提示。

emptyView简单使用Demo

下面展示emptyView使用的简单Demo。

activity_empty_list_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.littlejie.listview.EmptyListViewActivity"> <ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView> <!-- ListView的emptyView,默认不需设置其visiblity属性设置为GONE -->
<!-- 当ListView为空时,emptyView会自动被设置为GONE -->
<!-- 当ListView不为空时,emptyView会自动被设置为VIBISIBLE -->
<LinearLayout
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Empty" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="EmptyView可以是ViewGroup" />
</LinearLayout> </LinearLayout>

EmptyListViewActivity.java:

public class EmptyListViewActivity extends Activity {

    private ListView mLv;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_empty_list_view); mLv = (ListView) findViewById(R.id.lv);
mLv.setAdapter(new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, generateString(0)));
mLv.setEmptyView(findViewById(android.R.id.empty));
} private List<String> generateString(int num) {
List<String> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add("item " + i);
}
return list;
} }

运行结果如下:

emptyView复杂使用Demo

前一个Demo讲了emptyView的简单使用方法,那如果我们要自定义emptyView或者emptyView的布局跟ListView不在同一个布局文件中呢?恩,你可能会说:直接调用setEmptyView(View emptyView)不行嘛,难道有啥不一样?
看来,你还是too young too simple。直接调用的结果就是:emptyView根本就不会显示!!!
新建一个ComplexEmptyListViewActivity.java:

public class ComplexEmptyListViewActivity extends Activity {

    private ListView mLv;
private EmptyView mEmptyView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_complex_empty_list_view); mLv = (ListView) findViewById(R.id.lv);
mLv.setAdapter(new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, Utils.generateString(0))); mEmptyView = new EmptyView(this);
//此处是重点,如果不将mEmptyView添加进当前的ViewGroup,mEmptyView都不可见
//((ViewGroup) mLv.getParent()).addView(mEmptyView);
mLv.setEmptyView(mEmptyView);
}
}

布局文件activity_complex_empty_list_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.littlejie.listview.EmptyListViewActivity"> <ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView> </LinearLayout>

EmptyView:

public class EmptyView extends LinearLayout {

    public EmptyView(Context context) {
super(context);
init(context);
} public EmptyView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
} private void init(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.complex_empty_view, this);
}
}

complex_empty_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="假装我是复杂的emptyView" /> </LinearLayout>

运行demo,你会发现ListView为空时,根本就没显示emptyView。这是为什么呢?因为emptyView根本就没添加到当前Activity的布局中,所以即使设置了emptyView也不会显示,解决方法就是把emptyView添加到当前Activity的布局中(ComplexEmptyListViewActivity注释的内容)

补充

  1. 细心的可能已经发现,在两个demo中,我们都没去设置emptyView的visiblity属性,这是为什么呢?其实看下源码就知道了~

    当调用setEmptyView(View emptyView)方法时,ListView会调用到updateEmptyStatus(boolean empty),在这里系统会跟empty去判断是否显示emptyView。恩,就这么简单~

    /**
    * Sets the view to show if the adapter is empty
    */
    @android.view.RemotableViewMethod
    public void setEmptyView(View emptyView) {
    mEmptyView = emptyView; // If not explicitly specified this view is important for accessibility.
    if (emptyView != null
    && emptyView.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
    emptyView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
    } final T adapter = getAdapter();
    final boolean empty = ((adapter == null) || adapter.isEmpty());
    updateEmptyStatus(empty);
    } /**
    * 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);
    }
    }

给ListView设置emptyView的更多相关文章

  1. android: ListView设置emptyView 误区

    使用ListVIew 来设置EmptyView的时候须注意: ListView listview = (ListView) findViewById(R.id.list); View emptyVie ...

  2. ListView之EmptyView

    From:http://blog.csdn.net/xiangqiao123/article/details/17994099 继承ListActivity比较方便 最新开发一个应用程序,需要用到当L ...

  3. 在为ListView设置adapter时出错

    为listView设置adapter,代码如下: SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.m ...

  4. 【转】三十三、Android给ListView设置分割线Divider样式

    原文网址:http://www.cnblogs.com/linjiqin/archive/2011/11/12/2246349.html 给ListView设置分割线,只需设置如下两个属性: andr ...

  5. Android给ListView设置分割线Divider样式

    给ListView设置分割线,只需设置如下两个属性: android:divider="#000" //设置分割线显示颜色 android:dividerHeight=" ...

  6. Android ListView 设置单选

    为 ListView 设置选中状态,需要经过如下几个步骤: 设置 ListView 的 android:choiceMode="singleChoice" 设置 ListView ...

  7. WPF,ListView设置分组

    原文:WPF,ListView设置分组 今天遇到一个问题,就是在ListView中设置分组.想了很久在网上早了些资料作出一个例子. 分组字段也可以在后台中定义: CollectionView view ...

  8. Android开发之ListView设置隔行变色

    public class HLCheckAdapter extends BaseAdapter { private List<HuoLiang> list; private Context ...

  9. Android下用程序的方法为ListView设置分割线Divider样式

    使用XML的时候可以使用android:divider属性为ListView设置分割线的样式(颜色或者资源文件),而在Java代码中默认提供的方法 listView.setDivider() 却只支持 ...

随机推荐

  1. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

  2. JAVA语言中的修饰符

    JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...

  3. 网站定位之---根据IP获得区域

    记得以前做一个培训机构网站时候需要定位,那时候用的搜狐的api,不是很精准. demo:https://github.com/dunitian/LoTCodeBase/tree/master/NetC ...

  4. HTML5 progress和meter控件

    在HTML5中,新增了progress和meter控件.progress控件为进度条控件,可表示任务的进度,如Windows系统中软件的安装.文件的复制等场景的进度.meter控件为计量条控件,表示某 ...

  5. Mysql事务探索及其在Django中的实践(二)

    继上一篇<Mysql事务探索及其在Django中的实践(一)>交代完问题的背景和Mysql事务基础后,这一篇主要想介绍一下事务在Django中的使用以及实际应用给我们带来的效率提升. 首先 ...

  6. 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)

    建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...

  7. html中table边框属性

    1.向右(横向)合并: <td colspan="5"><span>后台管理系统</span></td> 2.向下(纵向)合并: & ...

  8. JavaScript知识结构图

    画的一个知识结构图,方便理解.

  9. SVG:textPath深入理解

    SVG的文本可以沿着一条自定义的Path来排布,比如曲线.圆形等等,使用方式如下所示(来源MDN): <svg viewBox="0 0 1000 300" xmlns=&q ...

  10. 分布式存储 FastDFS-5.0.5线上搭建

    前言:       由于公司项目需要,最近开始学习一下分布式存储相关知识,确定使用FastDFS这个开源工具.学习之初,自己利用VMware虚拟机搭建了一个5台机器的集群,摸清了安装过程中可能出现的问 ...