一個(gè)通用的加載幫助類斗蒋,Loading如此舒服

本文出自 “阿敏其人” 簡(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展示圖.gif
Paste_Image.png

在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

Paste_Image.png

可以看到,代碼非常簡(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的類加載器愧旦。

下載鏈接
本篇完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碘举,一起剝皮案震驚了整個(gè)濱河市忘瓦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌引颈,老刑警劉巖耕皮,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蝙场,居然都是意外死亡凌停,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門售滤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)罚拟,“玉大人,你說(shuō)我怎么就攤上這事完箩〈退祝” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵弊知,是天一觀的道長(zhǎng)阻逮。 經(jīng)常有香客問(wèn)我,道長(zhǎng)秩彤,這世上最難降的妖魔是什么叔扼? 我笑而不...
    開(kāi)封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮漫雷,結(jié)果婚禮上瓜富,老公的妹妹穿的比我還像新娘。我一直安慰自己降盹,他們只是感情好与柑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蓄坏,像睡著了一般仅胞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剑辫,一...
    開(kāi)封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天干旧,我揣著相機(jī)與錄音,去河邊找鬼妹蔽。 笑死椎眯,一個(gè)胖子當(dāng)著我的面吹牛挠将,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播编整,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼舔稀,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了掌测?” 一聲冷哼從身側(cè)響起内贮,我...
    開(kāi)封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汞斧,沒(méi)想到半個(gè)月后夜郁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡粘勒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年竞端,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庙睡。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡事富,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出乘陪,到底是詐尸還是另有隱情统台,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布啡邑,位于F島的核電站贱勃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谣拣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一族展、第九天 我趴在偏房一處隱蔽的房頂上張望森缠。 院中可真熱鬧,春花似錦仪缸、人聲如沸贵涵。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宾茂。三九已至,卻和暖如春拴还,著一層夾襖步出監(jiān)牢的瞬間跨晴,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工片林, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留端盆,地道東北人怀骤。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像焕妙,于是被迫代替她去往敵國(guó)和親蒋伦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,732評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)焚鹊、插件痕届、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,058評(píng)論 4 62
  • 不要把別人的善言善行當(dāng)心靈雞湯喝掉,或者端了去又灌給其他人喝末患,而是要切己體察研叫,馬上落實(shí)到自己身上。不要廉價(jià)的感動(dòng)和...
    華杉2009閱讀 666評(píng)論 0 0
  • “我死了之后,想必就會(huì)有答案了吧陈莽?可惜渤昌,這個(gè)答案我卻看不到∽吒椋” 阿炳將子彈按進(jìn)了彈夾独柑。接下來(lái)的程序,應(yīng)該是把槍口對(duì)...
    說(shuō)啥看心情閱讀 494評(píng)論 0 2