给ListView设置emptyView
给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注释的内容)。
补充
细心的可能已经发现,在两个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的更多相关文章
- android: ListView设置emptyView 误区
使用ListVIew 来设置EmptyView的时候须注意: ListView listview = (ListView) findViewById(R.id.list); View emptyVie ...
- ListView之EmptyView
From:http://blog.csdn.net/xiangqiao123/article/details/17994099 继承ListActivity比较方便 最新开发一个应用程序,需要用到当L ...
- 在为ListView设置adapter时出错
为listView设置adapter,代码如下: SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.m ...
- 【转】三十三、Android给ListView设置分割线Divider样式
原文网址:http://www.cnblogs.com/linjiqin/archive/2011/11/12/2246349.html 给ListView设置分割线,只需设置如下两个属性: andr ...
- Android给ListView设置分割线Divider样式
给ListView设置分割线,只需设置如下两个属性: android:divider="#000" //设置分割线显示颜色 android:dividerHeight=" ...
- Android ListView 设置单选
为 ListView 设置选中状态,需要经过如下几个步骤: 设置 ListView 的 android:choiceMode="singleChoice" 设置 ListView ...
- WPF,ListView设置分组
原文:WPF,ListView设置分组 今天遇到一个问题,就是在ListView中设置分组.想了很久在网上早了些资料作出一个例子. 分组字段也可以在后台中定义: CollectionView view ...
- Android开发之ListView设置隔行变色
public class HLCheckAdapter extends BaseAdapter { private List<HuoLiang> list; private Context ...
- Android下用程序的方法为ListView设置分割线Divider样式
使用XML的时候可以使用android:divider属性为ListView设置分割线的样式(颜色或者资源文件),而在Java代码中默认提供的方法 listView.setDivider() 却只支持 ...
随机推荐
- 前端框架 EasyUI (1)熟悉一下EasyUI
jQuery EasyUI 官方网站 http://www.jeasyui.com/ .去年新开了个中文网 http://www.jeasyui.net/,不知道是不是官方的,不过看着挺像样.但是,广 ...
- ExtJS 4.2 第一个程序
本篇介绍如何创建一个ExtJS应用程序.并通过创建目录.导入文件.编写代码及分析代码等步骤来解释第一个ExtJS程序. 目录 1. 创建程序 1.1 创建目录建议 1.2 实际目录 1.3 index ...
- CodeSimth - .Net Framework Data Provider 可能没有安装。解决方法
今天想使用CodeSimth生成一个sqlite数据库的模板.当添加添加数据库的时候发现: .Net Framework Data Provider 可能没有安装. 下面找到官方的文档说明: SQLi ...
- H5坦克大战之【画出坦克】
今天是个特殊的日子,圣诞节,也是周末,在这里先祝大家圣诞快乐!喜庆的日子,我们可以稍微放松一下,扯一扯昨天雷霆对战凯尔特人的比赛,这场比赛大威少又双叒叕拿下三双,而且是一个45+11+11的超级三双, ...
- ASP.NET 5 RC1 升级 ASP.NET Core 1.0 RC2 记录
升级文档: Migrating from DNX to .NET Core Migrating from ASP.NET 5 RC1 to ASP.NET Core 1.0 RC2 Migrating ...
- Javascript 代理模式模拟一个文件同步功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- obj.style.z-index的正确写法
obj.style.z-index的正确写法 今天发现obj.style.z-index在js里面报错,后来才知道在js里应该把含"-"的字符写成驼峰式,例如obj.style.z ...
- 代码的坏味道(16)——纯稚的数据类(Data Class)
坏味道--纯稚的数据类(Data Class) 特征 纯稚的数据类(Data Class) 指的是只包含字段和访问它们的getter和setter函数的类.这些仅仅是供其他类使用的数据容器.这些类不包 ...
- Node.js使用PM2的集群将变得更加容易
介绍 众所周知,Node.js运行在Chrome的JavaScript运行时平台上,我们把该平台优雅地称之为V8引擎.不论是V8引擎,还是之后的Node.js,都是以单线程的方式运行的,因此,在多核心 ...
- [Unity3D]利用Raycast实现物体的选择与操作
本文系作者原创 转载请注明出处 如果是一个2D的平面项目或者说需要在三维空间选择一个物体时(经常表现为抓取物件),我们需要用到Raycast事件 那么首先先说说什么是Raycast 按照字面上来理解的 ...