Android ListView的setEmptyView方法的使用

Android开发中,经常会用到ListView显示数据,但是当ListView中没有数据的时候,如果显示一片空白,对用户来说是个不太好的体验,我们可以在ListView中没数据的时候给用户一个提示,如暂无数据之类,在没有用到ListView的setEmptyView方法之前,我的做法是,在ListView的下面放一个用来显示提示信息的布局,当ListView为空时就隐藏ListView,显示提示信息布局,当ListView不为空的时候就显示ListView,隐藏提示信息布局,这种做法虽然能达到效果,但是稍微有点繁琐,其实ListView已经自带了一个setEmptyView方法了,可以为ListView设置一个空布局,当ListView中没数据时会自动显示空布局,下面是对setEmptyView方法的一个测试

1、首先是布局文件,MainActivity的布局文件如下:

 

[html] view plain copy
 
 print?
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.               xmlns:tools="http://schemas.android.com/tools"  
  3.               android:layout_width="match_parent"  
  4.               android:layout_height="match_parent"  
  5.               android:orientation="vertical"  
  6.               tools:context=".MainActivity">  
  7.   
  8.     <ListView  
  9.         android:id="@+id/listview"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="match_parent"/>  
  12.   
  13.     <include  
  14.         android:id="@+id/emptyview"  
  15.         layout="@layout/empty_list_layout"/>  
  16.   
  17. </LinearLayout>  

布局文件的内容很简单,就是一个ListView,ListView是充满父容器的,在ListView的下面引入了一个emptyView,这个布局的代码如下:

 

 

[html] view plain copy
 
 print?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.               android:orientation="vertical"  
  4.               android:layout_width="match_parent"  
  5.               android:layout_height="match_parent">  
  6.   
  7.     <TextView  
  8.         android:gravity="center"  
  9.         android:textSize="18sp"  
  10.         android:textColor="#000000"  
  11.         android:text="No Data"  
  12.         android:layout_width="match_parent"  
  13.         android:layout_height="match_parent"/>  
  14.   
  15. </LinearLayout>  

这里需要注意的是,ListView和emptyView的宽高都是充满父容器

 

2、代码设置,MainActivity的代码如下:

 

[html] view plain copy
 
 print?
  1. package listome.com.testlistview;  
  2.   
  3. import android.support.v7.app.AppCompatActivity;  
  4. import android.os.Bundle;  
  5. import android.view.LayoutInflater;  
  6. import android.view.Menu;  
  7. import android.view.MenuItem;  
  8. import android.view.View;  
  9. import android.view.ViewGroup;  
  10. import android.widget.BaseAdapter;  
  11. import android.widget.ListView;  
  12. import android.widget.TextView;  
  13.   
  14. import java.util.ArrayList;  
  15. import java.util.List;  
  16.   
  17. public class MainActivity extends AppCompatActivity {  
  18.   
  19.     private ListView listView;  
  20.     private View emptyView;  
  21.     private MyAdapter adapter;  
  22.   
  23.     @Override  
  24.     protected void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(R.layout.activity_main);  
  27.         initView();  
  28.     }  
  29.   
  30.     private void initView(){  
  31.         listView = (ListView) findViewById(R.id.listview);  
  32.         emptyView = findViewById(R.id.emptyview);  
  33.         listView.setEmptyView(emptyView);  
  34.         List<Stringdata = new ArrayList<>();  
  35.         for(int i = 0; i 10; i++){  
  36.             data.add("item" + i);  
  37.         }  
  38.         adapter = new MyAdapter(data);  
  39.         listView.setAdapter(adapter);  
  40.     }  
  41.   
  42.     private class MyAdapter extends BaseAdapter{  
  43.   
  44.         private List<String> names;  
  45.   
  46.         public MyAdapter(List<String> names){  
  47.             this.names = names;  
  48.         }  
  49.   
  50.         @Override  
  51.         public int getCount() {  
  52.             return names.size();  
  53.         }  
  54.   
  55.         @Override  
  56.         public String getItem(int position) {  
  57.             return names.get(position);  
  58.         }  
  59.   
  60.         @Override  
  61.         public long getItemId(int position) {  
  62.             return position;  
  63.         }  
  64.   
  65.         @Override  
  66.         public View getView(int position, View convertView, ViewGroup parent) {  
  67.             TextView tv = new TextView(MainActivity.this);  
  68.             tv.setPadding(10, 10, 0, 10);  
  69.             tv.setTextSize(20);  
  70.             tv.setText(getItem(position));  
  71.             return tv;  
  72.         }  
  73.     }  
  74.   
  75. }  

这里的代码很简单,需要注意的是,我们获取到emptyView后,调用了ListView的setEmptyView方法,传入了emptyView,当initView方法中的for循环没有被注释掉时,程序运行的结果如下图:

 


当initView方法中的for循环被注释掉时,或者我们直接设置listView.setAdapter(null),再执行程序时,运行效果如下图:

可以看到设置ListView的emptyView起到了效果,当ListView中没有数据的时候,就显示出了我们设置的emptyView,其实在setEmptyView方法的内部,处理方法跟开始我们说的方法是一样的,下面是setEmptyView方法的源代码:

 

[html] view plain copy
 
 print?
  1. public void setEmptyView(View emptyView) {  
  2.         mEmptyView = emptyView;  
  3.   
  4.         // If not explicitly specified this view is important for accessibility.  
  5.         if (emptyView != null  
  6.                 && emptyView.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {  
  7.             emptyView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);  
  8.         }  
  9.   
  10.         final T adapter = getAdapter();  
  11.         final boolean empty = ((adapter == null) || adapter.isEmpty());  
  12.         updateEmptyStatus(empty);  
  13.     }  

其中有一个boolean类型的empty变量,当ListView的adapter为空时,或者ListView的adapter中没有数据时,就显示空布局,隐藏ListView,这个处理在updateEmptyStatus方法中,如下代码所示:

 

 

[html] view plain copy
 
 print?
  1. private void updateEmptyStatus(boolean empty) {  
  2.         if (isInFilterMode()) {  
  3.             empty = false;  
  4.         }  
  5.   
  6.         if (empty) {  
  7.             if (mEmptyView != null) {  
  8.                 mEmptyView.setVisibility(View.VISIBLE);  
  9.                 setVisibility(View.GONE);  
  10.             } else {  
  11.                 // If the caller just removed our empty view, make sure the list view is visible  
  12.                 setVisibility(View.VISIBLE);  
  13.             }  
  14.   
  15.             // We are now GONE, so pending layouts will not be dispatched.  
  16.             // Force one here to make sure that the state of the list matches  
  17.             // the state of the adapter.  
  18.             if (mDataChanged) {             
  19.                 this.onLayout(false, mLeft, mTop, mRight, mBottom);   
  20.             }  
  21.         } else {  
  22.             if (mEmptyView != null) mEmptyView.setVisibility(View.GONE);  
  23.             setVisibility(View.VISIBLE);  
  24.         }  
  25.     }  

可以看到,当empty变量为true时,就隐藏了ListView,显示了emptyView,否则就显示ListView,隐藏emptyView。

posted @ 2017-04-25 11:26  天涯海角路  阅读(356)  评论(0)    收藏  举报