场景分析:
在app开发中,我们为了保证用户体验往往需要在有ListView的地方添加加载中动画及数据为空的时候的提示界面,那么让我们一起来用最简单高效的方法去实现一下吧
第一步:设计空数据布局文件view_empty.xml
<?xml version="1.0" encoding="utf-8"?>
<cn.xx.widget.EmptyView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/empty_background" />
<TextView
android:id="@+id/txt_empty_tip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="35dp"
android:text="@string/no_empty_tip"
android:textColor="@color/empty_text_color"
android:textSize="@dimen/font_size_16sp" />
</LinearLayout>
</cn.xx.widget.EmptyView>
此处我们看到使用了一个自定义View,对,在这里我们需要简单封装一下,设想在每一个界面,我们在数据为空的时候的提示信息可能会不一样,所以我们来看看怎么设计这个EmptyView吧
第二步:封装EmptyView.java
import android.content.Context;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* 数据为空的界面
* Created by ccwant on 2016/9/8.
*/
public class EmptyView extends RelativeLayout {
private TextView mTxtEmptyTip;
public EmptyView(Context context) {
super(context);
}
public EmptyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EmptyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mTxtEmptyTip=(TextView)findViewById(R.id.txt_empty_tip);
}
/**
* 设置提示信息
* @param tip
*/
public void setEmptyTip(String tip){
mTxtEmptyTip.setText(tip);
}
/**
* 设置提示信息
* @param resId
*/
public void setEmptyTip(int resId){
mTxtEmptyTip.setText(resId);
}
}
此处我们注意到一个特殊的方法onFinishInflate,它是在xml布局加载完成之后调用的一个方法,在这里我们就可以获取到对应的子View对象了,然后我们在来看看EmptyView具体的用法
第三步:设计activity_main.xml
<span style="font-size:14px;"><?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:fitsSystemWindows="true"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ListView
android:id="@+id/lst_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@drawable/list_divider"
android:dividerHeight="0.3dp"
/>
<include
android:id="@+id/inc_empty_view"
layout="@layout/view_empty"></include>
<include
android:id="@+id/inc_loading_view"
layout="@layout/view_loading"
></include>
</FrameLayout>
</LinearLayout>
</span>
此处我们看到使用了帧布局,整个界面分三层,第一层是ListView控件,第二层是空数据界面,第三层是加载中界面
然后我们看看怎么去控制EmptyView显示隐藏,很多人对这里都是手动去判断,但是其实有一个非常简单的使用方法。在ListView中已经帮我们实现了这件事,只是很多人不知道ListView的setEmptyView方法
第四步:setEmptyView
mIEmptyView=(EmptyView)findViewById(R.id.inc_empty_view);
mIEmptyView.setEmptyTip("暂无数据");
mLstContent.setEmptyView(mIEmptyView);
ok,到这一步空数据层已经处理完毕了
第五步:设计加载中布局view_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<cn.xx.widget.LoadingView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:visibility="visible">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="@+id/img_loading"
android:layout_width="120dp"
android:layout_height="120dp"
android:src="@drawable/bg_loading"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="努力加载中..."
android:textColor="#aeaeae"
android:textSize="@dimen/font_size_16sp"/>
</LinearLayout>
</cn.xx.widget.LoadingView>
我们看到界面上显示了一个ImageView,这里主要用于显示帧动画效果
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false"
>
<item
android:drawable="@drawable/bg_loading1"
android:duration="150"></item>
<item
android:drawable="@drawable/bg_loading2"
android:duration="150"></item>
<item
android:drawable="@drawable/bg_loading3"
android:duration="150"></item>
<item
android:drawable="@drawable/bg_loading4"
android:duration="150"></item>
</animation-list>
此处我们同样需要对LoadingView进行封装处理
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
/**
* 数据加载中的界面
* Created by ccwant on 2016/9/8.
*/
public class LoadingView extends RelativeLayout {
private ImageView mImgLoading;
public LoadingView(Context context) {
super(context);
}
public LoadingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 显示正在加载界面
*/
public void showLoading(){
setVisibility(View.VISIBLE);
((AnimationDrawable)mImgLoading.getDrawable()).start();
}
/**
* 隐藏正在加载界面
*/
public void hideLoading(){
setVisibility(View.GONE);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mImgLoading=(ImageView)findViewById(R.id.img_loading);
}
}
第六步:LoadingView的使用
它的使用方法就需要我们去手动调用了,在界面刚进来第一次请求网络数据的时候调用showLoading方法,在请求完数据的时候调用hideLoading方法