10月底的時候去網易面試,感覺其他發揮都不錯,就listview這塊被虐了。回家痛定思痛,開始研究listview的源碼,從adapterView開始看起,想到了一個比較有趣的技巧,可以方便的管理我們項目中listview數據爲空時EmptyView。廢話不多說,先來看看EmptyView
關於Empty的機制,就是當listview的getCount爲0的時候,就顯示EmptyView。
具體的效果圖是這這樣的
點擊empty的時候清空數據,顯示emptyView,點擊show data的時候,再把數據加載進來
emptyView本身的用法並不複雜,但是我發現很多項目裏每用到一個listview都會去寫一個新的emptyview,這不光違反重用的原則,而且有可能因爲不同人去維護項目而導致每個emptyview的樣式不同,破壞了一個app的統一性,會讓用戶看起來很凌亂。
因此,我在這提出一個概念,每個項目主要實現一個emptyview,爲不同的listview甚至webview服務。然後留出一個接口,用於實現具體的emptyview點擊實現的業務
讓我們先來看看emptyview的實現
package com.example.emptyviewdemo;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class EmptyView extends RelativeLayout{
private OnEmptyViewListener mOnEmptyViewListener;
private TextView mEmptyTv;
public EmptyView(Context context) {
super(context);
}
public EmptyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mEmptyTv = (TextView) findViewById(R.id.empty_textview);
mEmptyTv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mOnEmptyViewListener != null) {
mOnEmptyViewListener.onEmptyViewClick();
}
}
});
}
public void setOnEmptyViewListener(OnEmptyViewListener listener){
this.mOnEmptyViewListener = listener;
}
}
其實很簡單,只是留出了一個接口實現點擊效果
接下來是佈局文件,你可以把這個佈局改成任何你想要的樣子,下面的xml只是舉了一個例子
<?xml version="1.0" encoding="utf-8"?>
<com.example.emptyviewdemo.EmptyView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" >
<TextView
android:id="@+id/empty_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:drawablePadding="15dp"
android:drawableTop="@drawable/friends_sends_pictures_no"
android:gravity="center"
android:text="there is no data" />
</com.example.emptyviewdemo.EmptyView>
然後爲了幫助大家更好的理解,我幫上面圖片的實現邏輯貼出來給大家看下
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private EmptyView mEmptyView;
private ListView mListView;
private Activity activity;
private List<String> data;
private MyAdapter mAdapter;
private Button mEmptyBtn;
private Button mShowDataBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEmptyView = (EmptyView) findViewById(R.id.empty_view);
mListView = (ListView) findViewById(R.id.my_listview);
mShowDataBtn = (Button) findViewById(R.id.show_data_button);
mEmptyBtn = (Button) findViewById(R.id.empty_button);
activity = this;
initData();
mAdapter = new MyAdapter(activity);
mListView.setAdapter(mAdapter);
mAdapter.setData(data);
mListView.setEmptyView(mEmptyView);
mEmptyView.setOnEmptyViewListener(new OnEmptyViewListener() {
@Override
public void onEmptyViewClick() {
Toast.makeText(activity, "EmptyView被點擊啦!", Toast.LENGTH_LONG).show();
}
});
mShowDataBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mAdapter.setData(data);
}
});
mEmptyBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mAdapter.emptyData();
}
});
}
private void initData(){
data = new ArrayList<String>();
data.add("星期一");
data.add("星期二");
data.add("星期三");
data.add("星期四");
data.add("星期五");
data.add("星期六");
data.add("星期七");
}
private class MyAdapter extends BaseAdapter{
private List<String> data;
private Context context;
public MyAdapter(Context context){
this.context = context;
}
public void emptyData() {
if (this.data == null) {
this.data = new ArrayList<String>();
}
this.data.clear();
notifyDataSetChanged();
}
public void setData(List<String> data) {
if (this.data == null) {
this.data = new ArrayList<String>();
}
this.data.clear();
this.data.addAll(data);
notifyDataSetChanged();
}
@Override
public int getCount() {
if(data != null){
return data.size();
}
return 0;
}
@Override
public Object getItem(int position) {
if(data != null){
return data.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
if(data != null){
return data.get(position).hashCode();
}
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.item_view, null);
holder.mItemTv = (TextView) convertView.findViewById(R.id.item_textview);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.mItemTv.setText(data.get(position));
return convertView;
}
}
private class ViewHolder{
TextView mItemTv;
}
}
我們要對不同listview的emptyview點擊實現不同業務時,只要實現OnEmptyViewListener就行了
<RelativeLayout 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:background="@android:color/white" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/button_container"
android:orientation="vertical" >
<ListView
android:id="@+id/my_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
android:id="@+id/empty_view"
layout="@layout/empty_view" />
</LinearLayout>
<LinearLayout
android:id="@+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" >
<Button
android:id="@+id/empty_button"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:background="@android:color/holo_orange_dark"
android:gravity="center"
android:padding="15dp"
android:text="empty" />
<Button
android:id="@+id/show_data_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:background="@android:color/holo_orange_dark"
android:gravity="center"
android:padding="15dp"
android:text="show data" />
</LinearLayout>
</RelativeLayout>
值得注意的是當你在使用emptyview 的時候,你所使用的emptyview必須和listview保持在同一層級,就是屬於同一個parent。如果你是動態添加到activity中的,必須使用
((ViewGroup)mListView.getParent()).addView(mEmptyView);
最後說一句是,以前有一個前輩提出過一個概念:當你把一份同樣的代碼寫2邊的時候,就該想想是否能抽象出來,成爲了個公共方法
我覺得這句話挺受用的