Android ListView的setEmptyView方法的使用
在Android开发中,经常会用到ListView显示数据,但是当ListView中没有数据的时候,如果显示一片空白,对用户来说是个不太好的体验,我们可以在ListView中没数据的时候给用户一个提示,如暂无数据之类,在没有用到ListView的setEmptyView方法之前,我的做法是,在ListView的下面放一个用来显示提示信息的布局,当ListView为空时就隐藏ListView,显示提示信息布局,当ListView不为空的时候就显示ListView,隐藏提示信息布局,这种做法虽然能达到效果,但是稍微有点繁琐,其实ListView已经自带了一个setEmptyView方法了,可以为ListView设置一个空布局,当ListView中没数据时会自动显示空布局,下面是对setEmptyView方法的一个测试:
1、首先是布局文件,MainActivity的布局文件如下:
- <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=".MainActivity">
 - <ListView
 - android:id="@+id/listview"
 - android:layout_width="match_parent"
 - android:layout_height="match_parent"/>
 - <include
 - android:id="@+id/emptyview"
 - layout="@layout/empty_list_layout"/>
 - </LinearLayout>
 
布局文件的内容很简单,就是一个ListView,ListView是充满父容器的,在ListView的下面引入了一个emptyView,这个布局的代码如下:
- <?xml version="1.0" encoding="utf-8"?>
 - <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 - android:orientation="vertical"
 - android:layout_width="match_parent"
 - android:layout_height="match_parent">
 - <TextView
 - android:gravity="center"
 - android:textSize="18sp"
 - android:textColor="#000000"
 - android:text="No Data"
 - android:layout_width="match_parent"
 - android:layout_height="match_parent"/>
 - </LinearLayout>
 
这里需要注意的是,ListView和emptyView的宽高都是充满父容器
2、代码设置,MainActivity的代码如下:
- package listome.com.testlistview;
 - import android.support.v7.app.AppCompatActivity;
 - import android.os.Bundle;
 - import android.view.LayoutInflater;
 - import android.view.Menu;
 - import android.view.MenuItem;
 - import android.view.View;
 - import android.view.ViewGroup;
 - import android.widget.BaseAdapter;
 - import android.widget.ListView;
 - import android.widget.TextView;
 - import java.util.ArrayList;
 - import java.util.List;
 - public class MainActivity extends AppCompatActivity {
 - private ListView listView;
 - private View emptyView;
 - private MyAdapter adapter;
 - @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - setContentView(R.layout.activity_main);
 - initView();
 - }
 - private void initView(){
 - listView = (ListView) findViewById(R.id.listview);
 - emptyView = findViewById(R.id.emptyview);
 - listView.setEmptyView(emptyView);
 - List<String> data = new ArrayList<>();
 - for(int i = 0; i < 10; i++){
 - data.add("item" + i);
 - }
 - adapter = new MyAdapter(data);
 - listView.setAdapter(adapter);
 - }
 - private class MyAdapter extends BaseAdapter{
 - private List<String> names;
 - public MyAdapter(List<String> names){
 - this.names = names;
 - }
 - @Override
 - public int getCount() {
 - return names.size();
 - }
 - @Override
 - public String getItem(int position) {
 - return names.get(position);
 - }
 - @Override
 - public long getItemId(int position) {
 - return position;
 - }
 - @Override
 - public View getView(int position, View convertView, ViewGroup parent) {
 - TextView tv = new TextView(MainActivity.this);
 - tv.setPadding(10, 10, 0, 10);
 - tv.setTextSize(20);
 - tv.setText(getItem(position));
 - return tv;
 - }
 - }
 - }
 
这里的代码很简单,需要注意的是,我们获取到emptyView后,调用了ListView的setEmptyView方法,传入了emptyView,当initView方法中的for循环没有被注释掉时,程序运行的结果如下图:
当initView方法中的for循环被注释掉时,或者我们直接设置listView.setAdapter(null),再执行程序时,运行效果如下图:
可以看到设置ListView的emptyView起到了效果,当ListView中没有数据的时候,就显示出了我们设置的emptyView,其实在setEmptyView方法的内部,处理方法跟开始我们说的方法是一样的,下面是setEmptyView方法的源代码:
- 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);
 - }
 
其中有一个boolean类型的empty变量,当ListView的adapter为空时,或者ListView的adapter中没有数据时,就显示空布局,隐藏ListView,这个处理在updateEmptyStatus方法中,如下代码所示:
- 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);
 - }
 - }
 
可以看到,当empty变量为true时,就隐藏了ListView,显示了emptyView,否则就显示ListView,隐藏emptyView。
                    
                
                
            
        
浙公网安备 33010602011771号