本文出自 “阿敏其人” 簡(jiǎn)書博客捌斧,轉(zhuǎn)載或引用請(qǐng)注明出處。
首先泉沾,感謝github兩位同學(xué)的分享精神
XHLoadingView
LoadViewHelper
借這兩位的代碼骤星,做了一個(gè)稍微提取成為了一個(gè)mudule,可直接引入代碼使用爆哑。大家學(xué)習(xí)可以連接加星洞难,為開(kāi)源點(diǎn)贊。
一揭朝、你好队贱,Loading
我們加載Listview等,往往需要耗時(shí)幾秒潭袱,這和等待過(guò)程加上一些交互效果自然會(huì)讓人感覺(jué)輸入一些柱嫌,常見(jiàn)的轉(zhuǎn)圈圈自不必說(shuō),但是按照通常的想法屯换,我們往往是加xml里面的view通過(guò)隱藏和現(xiàn)實(shí)來(lái)實(shí)現(xiàn)编丘,這種方式實(shí)在不太方便与学,現(xiàn)在實(shí)現(xiàn)了一個(gè)ViewLoadHelp,直接通過(guò)構(gòu)造構(gòu)造方法傳入待loading的View嘉抓,方便快捷索守。
先上gif圖:
在loading的時(shí)候,大概可以分為幾種情況
1抑片、正在loading
2卵佛、load的時(shí)候發(fā)現(xiàn)異常
這個(gè)異常不論是服務(wù)器的,還是網(wǎng)絡(luò)敞斋,還是其他截汪,在這里我們都?xì)w為load異常,后面我們可以根據(jù)不同的異常顯示不同的提示圖片和提示語(yǔ)
3植捎、load后無(wú)數(shù)據(jù)
4衙解、load完成,成功得到數(shù)據(jù)并且展示數(shù)據(jù)
根據(jù)這幾種情況焰枢,我們的LoadViewHelp就可以寫上對(duì)應(yīng)的方法丢郊。
二、使用方式
第一步:
private LoadHelpView mLoadHelpView;
第二步医咨,指定LoadHelpView要load替換的View
mLoadHelpView = new LoadHelpView(mTvShow);
第三步:
該怎么load,該空數(shù)據(jù)架诞,該網(wǎng)絡(luò)異常拟淮,你看著辦
怎么顯示loading
mLoadHelpView.showLoading("正在為您拼命加載");
怎么顯示異常:
mLoadHelpView.showError("您的網(wǎng)絡(luò)怎么了?", "再試一下", R.drawable.load_error,new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});
嫌傳入的東西太長(zhǎng)谴忧?那么我們就傳一個(gè)短一點(diǎn)的:
mLoadHelpView.showError(new View.OnClickListener() {
@Override
public void onClick(View v) {
testNetError();
}
});
去掉load頁(yè)面
mLoadHelpView.dismiss();
三很泊、代碼簡(jiǎn)介
下圖是我們抽取出來(lái)的依賴module
可以看到,代碼非常簡(jiǎn)單沾谓,一個(gè)主要的LoadHelpView委造,另外一個(gè)IReplaceViewHelper接口,然后我們根據(jù)這個(gè)接口產(chǎn)生了一個(gè)實(shí)現(xiàn)類均驶,大家可以自己寫上自己合適的實(shí)現(xiàn)類昏兆。
接下看一下代碼:
LoadHelpView
/**
* 自定義要切換的布局,通過(guò)IVaryViewHelper實(shí)現(xiàn)真正的切換<br>
* 使用者可以根據(jù)自己的需求妇穴,使用自己定義的布局樣式
*/
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;
}
// 數(shù)據(jù)異常
public void showError(String errorText, String buttonText, int picResId,OnClickListener onClickListener) {
View layout = helper.inflate(R.layout.load_error);
// 設(shè)置圖片
ImageView mIvShowPic = (ImageView) layout.findViewById(R.id.mIvShowPic);
mIvShowPic.setBackgroundResource(picResId);
// 設(shè)置提示文字
TextView mTvTip = (TextView) layout.findViewById(R.id.mTvTip);
mTvTip.setText(errorText);
// 設(shè)置按鈕
TextView mTvBtn = (TextView) layout.findViewById(R.id.mTvBtn);
mTvBtn.setText(buttonText);
mTvBtn.setOnClickListener(onClickListener);
helper.showLayout(layout);
}
// 數(shù)據(jù)異常簡(jiǎn)易版
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);
}
// 空數(shù)據(jù)
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);
}
// 空數(shù)據(jù)簡(jiǎn)易版
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(); // 開(kāi)啟幀動(dòng)畫
mTvTip.setText(loadText);
helper.showLayout(layout);
}
public void dismiss() {
helper.dismissView();
}
}
.
.
關(guān)鍵接口 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();
}
.
.
參考實(shí)現(xiàn)類 ReplaceViewHelper
/**
* 用于切換布局,用一個(gè)新的布局替換掉原先的布局
*
*
*
*/
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;
// 如果已經(jīng)是那個(gè)view爬虱,那就不需要再進(jìn)行替換操作了
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;
}
}
通過(guò)來(lái)加載器LayoutInflater和LayoutParams,我們就可以進(jìn)行View的替換展示腾它。
以上是mudule庫(kù)的主要代碼
下面是主工程的引用后的實(shí)例代碼
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("您的網(wǎng)絡(luò)怎么了跑筝?", "再試一下", 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("暫無(wú)數(shù)據(jù),快去錄入新數(shù)據(jù)吧", "再試一下", 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("成功加載數(shù)據(jù)瞒滴,展示數(shù)據(jù)");
}
}, 1200);
}
}
再來(lái)看一下TestActivity的xml曲梗,我們看到我們無(wú)需在xml里面做替換View的隱藏和顯示。
<?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:background="#66000000"
android:orientation="vertical"
>
<TextView
android:id="@+id/mTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:background="#66ff0000"
android:padding="10dp"
android:text="加載數(shù)據(jù)"
android:textSize="20dp"
/>
<TextView
android:id="@+id/mTvShow"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:background="#660000ff"
android:gravity="center"
/>
</LinearLayout>
該有的應(yīng)該都有了,其實(shí)借此代碼虏两,還可以好好感受一下的android的類加載器愧旦。
下載鏈接
本篇完。