本文出自 “阿敏其人” 博客,转载或引用请注明出处。
首先,感谢github两位同学的分享精神
XHLoadingView
LoadViewHelper
借这两位的代码,做了一个稍微提取成为了一个mudule,可直接引入代码使用。大家学习可以连接加星,为开源点赞。
一、你好,Loading
我们加载Listview等,往往需要耗时几秒,这和等待过程加上一些交互效果自然会让人感觉输入一些,常见的转圈圈自不必说,但是按照通常的想法,我们往往是加xml里面的view通过隐藏和现实来实现,这种方式实在不太方便,现在实现了一个ViewLoadHelp,直接通过构造构造方法传入待loading的View,方便快捷。
先上gif图:
在loading的时候,大概可以分为几种情况
1、正在loading
2、load的时候发现异常
这个异常不论是服务器的,还是网络,还是其他,在这里我们都归为load异常,后面我们可以根据不同的异常显示不同的提示图片和提示语
3、load后无数据
4、load完成,成功得到数据并且展示数据
根据这几种情况,我们的LoadViewHelp就可以写上对应的方法。
二、使用方式
第一步:
private LoadHelpView mLoadHelpView;
第二步,指定LoadHelpView要load替换的View
mLoadHelpView = new LoadHelpView(mTvShow);
第三步:
该怎么load,该空数据,该网络异常,你看着办
怎么显示loading
mLoadHelpView.showLoading("正在为您拼命加载");
怎么显示异常:
mLoadHelpView.showError("您的网络怎么了?", "再试一下", R.drawable.load_error,new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});
嫌传入的东西太长?那么我们就传一个短一点的:
mLoadHelpView.showError(new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});
去掉load页面
mLoadHelpView.dismiss();
三、代码简介
下图是我们抽取出来的依赖module
可以看到,代码非常简单,一个主要的LoadHelpView,另外一个IReplaceViewHelper接口,然后我们根据这个接口产生了一个实现类,大家可以自己写上自己合适的实现类。
接下看一下代码:
LoadHelpView
/**
* 自定义要切换的布局,通过IVaryViewHelper实现真正的切换
* 使用者可以根据自己的需求,使用自己定义的布局样式
*/
public class LoadHelpView {
private IReplaceViewHelper helper;
private AnimationDrawable animationDrawable;
public LoadHelpView(View view) {
this(new ReplaceViewHelper(view));
}
public LoadHelpView(IReplaceViewHelper helper) {
super();
this.helper = helper;
}
// 数据异常
public void showError(String errorText, String buttonText, int picResId,OnClickListener onClickListener) {
View layout = helper.inflate(R.layout.load_error);
// 设置图片
ImageView mIvShowPic = (ImageView) layout.findViewById(R.id.mIvShowPic);
mIvShowPic.setBackgroundResource(picResId);
// 设置提示文字
TextView mTvTip = (TextView) layout.findViewById(R.id.mTvTip);
mTvTip.setText(errorText);
// 设置按钮
TextView mTvBtn = (TextView) layout.findViewById(R.id.mTvBtn);
mTvBtn.setText(buttonText);
mTvBtn.setOnClickListener(onClickListener);
helper.showLayout(layout);
}
// 数据异常简易版
public void showError(OnClickListener onClickListener) {
View layout = helper.inflate(R.layout.load_error);
TextView mTvBtn = (TextView) layout.findViewById(R.id.mTvBtn);
mTvBtn.setOnClickListener(onClickListener);
helper.showLayout(layout);
}
// 空数据
public void showEmpty(String errorText, String buttonText, int picResId,OnClickListener onClickListener) {
View layout = helper.inflate(R.layout.load_empty);
ImageView mIvShowPic = (ImageView) layout.findViewById(R.id.mIvShowPic);
mIvShowPic.setBackgroundResource(picResId);
TextView mTvTip = (TextView) layout.findViewById(R.id.mTvTip);
mTvTip.setText(errorText);
TextView mTvBtn = (TextView) layout.findViewById(R.id.mTvBtn);
mTvBtn.setText(buttonText);
mTvBtn.setOnClickListener(onClickListener);
helper.showLayout(layout);
}
// 空数据简易版
public void showEmpty(OnClickListener onClickListener) {
View layout = helper.inflate(R.layout.load_empty);
TextView mTvBtn = (TextView) layout.findViewById(R.id.mTvBtn);
mTvBtn.setOnClickListener(onClickListener);
helper.showLayout(layout);
}
// 正在加载
public void showLoading(String loadText) {
View layout = helper.inflate(R.layout.load_ing);
TextView mTvTip = (TextView) layout.findViewById(R.id.mTvTip);
ImageView mIvAnim = (ImageView) layout.findViewById(R.id.mIvAnim);
mIvAnim.setImageResource(R.drawable.loading_animation);
animationDrawable = (AnimationDrawable) mIvAnim.getDrawable();
animationDrawable.start(); // 开启帧动画
mTvTip.setText(loadText);
helper.showLayout(layout);
}
public void dismiss() {
helper.dismissView();
}
}
.
.
关键接口 IReplaceViewHelper
public interface IReplaceViewHelper {
public abstract View getCurrentLayout();
public abstract void dismissView();
public abstract void showLayout(View view);
public abstract void showLayout(int layoutId);
public abstract View inflate(int layoutId);
public abstract Context getContext();
public abstract View getView();
}
.
.
参考实现类 ReplaceViewHelper
/**
* 用于切换布局,用一个新的布局替换掉原先的布局
*
*
*
*/
public class ReplaceViewHelper implements IReplaceViewHelper {
private View view;
private ViewGroup parentView;
private int viewIndex;
private ViewGroup.LayoutParams params;
private View currentView;
public ReplaceViewHelper(View view) {
super();
this.view = view;
}
private void init() {
params = view.getLayoutParams();
if (view.getParent() != null) {
parentView = (ViewGroup) view.getParent();
} else {
parentView = (ViewGroup) view.getRootView().findViewById(android.R.id.content);
}
int count = parentView.getChildCount();
for (int index = 0; index < count; index++) {
if (view == parentView.getChildAt(index)) {
viewIndex = index;
break;
}
}
currentView = view;
}
@Override
public View getCurrentLayout() {
return currentView;
}
@Override
public void dismissView() {
showLayout(view);
}
@Override
public void showLayout(View view) {
if (parentView == null) {
init();
}
this.currentView = view;
// 如果已经是那个view,那就不需要再进行替换操作了
if (parentView.getChildAt(viewIndex) != view) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) {
parent.removeView(view);
}
parentView.removeViewAt(viewIndex);
parentView.addView(view, viewIndex, params);
}
}
@Override
public void showLayout(int layoutId) {
showLayout(inflate(layoutId));
}
@Override
public View inflate(int layoutId) {
return LayoutInflater.from(view.getContext()).inflate(layoutId, null);
}
@Override
public Context getContext() {
return view.getContext();
}
@Override
public View getView() {
return view;
}
}
通过来加载器LayoutInflater和LayoutParams,我们就可以进行View的替换展示。
以上是mudule库的主要代码
下面是主工程的引用后的实例代码
MainActivity
public class MainActivity extends Activity implements View.OnClickListener {
private TextView mTvLoad;
private TextView mTvNetError;
private TextView mTvNoData;
private TextView mTvLoadSuccess;
private Intent intent;
public static int LOAD = 1;
public static int NET_ERROR = 2;
public static int NO_DATA = 3;
public static int SUCEESS = 4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(MainActivity.this, TestActivity.class);
mTvLoad = (TextView) findViewById(R.id.mTvLoad);
mTvNetError = (TextView) findViewById(R.id.mTvNetError);
mTvNoData = (TextView) findViewById(R.id.mTvNoData);
mTvLoadSuccess = (TextView) findViewById(R.id.mTvLoadSuccess);
mTvLoad.setOnClickListener(this);
mTvNetError.setOnClickListener(this);
mTvNoData.setOnClickListener(this);
mTvLoadSuccess.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.mTvLoad:
intent.putExtra("TYPE", LOAD);
startActivity(intent);
break;
case R.id.mTvNetError:
intent.putExtra("TYPE", NET_ERROR);
startActivity(intent);
break;
case R.id.mTvNoData:
intent.putExtra("TYPE", NO_DATA);
startActivity(intent);
break;
case R.id.mTvLoadSuccess:
intent.putExtra("TYPE", SUCEESS);
startActivity(intent);
break;
}
}
}
.
.
TestActivity
public class TestActivity extends Activity{
private TextView mTv;
private TextView mTvShow;
private LoadHelpView mLoadHelpView;
private Intent mIntent;
private int mType;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mTv = (TextView) findViewById(R.id.mTv);
mTvShow = (TextView) findViewById(R.id.mTvShow);
mLoadHelpView = new LoadHelpView(mTvShow);
mIntent = getIntent();
mType = mIntent.getIntExtra("TYPE", -1);
mTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mType == MainActivity.LOAD){
mLoadHelpView.showLoading("正在为您拼命加载");
}else if(mType == MainActivity.NET_ERROR){
testNetError();
}else if(mType == MainActivity.NO_DATA){
testNoData();
}else if(mType == MainActivity.SUCEESS){
testSuccess();
}
}
});
}
private void testNetError(){
mLoadHelpView.showLoading("正在为您拼命加载");
new Handler().postDelayed(new Runnable(){
public void run() {
/*mLoadHelpView.showError("您的网络怎么了?", "再试一下", R.drawable.load_error,new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});*/
mLoadHelpView.showError(new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});
}
}, 1200);
}
private void testNoData(){
mLoadHelpView.showLoading("正在为您拼命加载");
new Handler().postDelayed(new Runnable(){
public void run() {
/*mLoadHelpView.showEmpty("暂无数据,快去录入新数据吧", "再试一下", R.drawable.load_no_data,new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});*/
mLoadHelpView.showEmpty(new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});
}
}, 1200);
}
private void testSuccess(){
mLoadHelpView.showLoading("正在为您拼命加载");
new Handler().postDelayed(new Runnable(){
public void run() {
mLoadHelpView.dismiss();
mTvShow.setText("成功加载数据,展示数据");
}
}, 1200);
}
}
再来看一下TestActivity的xml,我们看到我们无需在xml里面做替换View的隐藏和显示。
该有的应该都有了,其实借此代码,还可以好好感受一下的android的类加载器。
下载链接
本篇完。