高效抽取loading,再多的加载页面也不怕

当今的app基本上有两个操作,一个是加载数据 ,一个就是把数据显示到页面上。但如果页面特别的多。就每个页面都要加载数据,就要写 loading 页面。我之前就是用dialog写,抽取出来一个类。哪里需要了就在那里添加以下代码。我发现我大多数时间都在 重复的 添加 loading代码。为此总加班。

请无限参考此文章:http://blog.csdn.net/wanghao200906/article/details/46805085

下面是页面多的时候状态

这要再多点儿 一个一个的写不但代码不好看,自己也累得慌

下面我们就来说一下如何高效的写loading了。

一般页面有四种情况

加载中 :就是滚动页面,后台获取加载的数据,每个页面的数据不同所以就让子类来实现,直接抽象abstract了。

加载失败 :一般都需要点击后重新加载

空页面 :也需要点击后重新加载

加载成功 :显示成功的页面,每个页面都不同所以让子类实现,那必须是抽象的 abstract了

我采取的是每个页面都是framelayout来显示 加载的页面。一共有四个页面。通过加载的数据返回来的 状态 进而让页面显示相应的动画

先屡一下思路

1 先加载三个页面,开始都执行loading页面

2 加载数据, 用到了线程池处理耗时炒作,具体如何访问网络让子类来实现判断数据是否可用

3 数据可用显示 成功界面

数据不可用显示 加载失败页面

数据的list比如为0 加载空页面

下面直接上代码时间:

package com.example.every_text.view;

import com.wang.cn.manager.ThreadManager;
import com.wang.cn.utils.UIUtils;

import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;

/**
 * 先加顺序 load -->showPagerView-->createSuccessView
 *
 * @author wanghao
 *
 *在子类中 耗时操作放到 load中,然后load返回一个状态,在showPagerView中根据状态选择 显示的页面
 *如果装在是成功的。那么久显示 createSuccessView
 */
public abstract class LoadingPager extends FrameLayout {

    // 加载默认的状态
    private static final int STATE_UNLOADED = 1;
    // 加载的状态
    private static final int STATE_LOADING = 2;
    // 加载失败的状态
    private static final int STATE_ERROR = 3;
    // 加载空的状态
    private static final int STATE_EMPTY = 4;
    // 加载成功的状态
    private static final int STATE_SUCCEED = 5;

    private View mLoadingView;// 转圈的view
    private View mErrorView;// 错误的view
    private View mEmptyView;// 空的view
    private View mSucceedView;// 成功的view

    private int mState;// 默认的状态

    private int loadpage_empty;
    private int loadpage_error;
    private int loadpage_loading;

    public LoadingPager(Context context, int loading, int error, int empty) {
        super(context);
        loadpage_empty = empty;
        loadpage_error = error;
        loadpage_loading = loading;
        init();
    }

    public LoadingPager(Context context, AttributeSet attrs, int defStyle,
            int loading, int error, int empty) {
        super(context, attrs, defStyle);
        loadpage_empty = empty;
        loadpage_error = error;
        loadpage_loading = loading;
        init();
    }

    public LoadingPager(Context context, AttributeSet attrs, int loading,
            int error, int empty) {
        super(context, attrs);

        init();
    }
    private void init() {
        // 初始化状态
        mState = STATE_UNLOADED;
        // 初始化三个 状态的view 这个时候 三个状态的view叠加在一起了
        mLoadingView = createLoadingView();
        if (null != mLoadingView) {
            addView(mLoadingView, new LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.MATCH_PARENT));
        }
        mErrorView = createErrorView();
        if (null != mErrorView) {
            addView(mErrorView, new LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.MATCH_PARENT));
        }
        mEmptyView = createEmptyView();
        if (null != mEmptyView) {
            addView(mEmptyView, new LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.MATCH_PARENT));
        }
        showSafePagerView();
    }
    private void showSafePagerView() {
        // 直接运行到主线程
        UIUtils.runInMainThread(new Runnable() {
            @Override
            public void run() {
                showPagerView();
            }
        });
    }
    private void showPagerView() {

        // 這個時候 都不為空 mState默認是STATE_UNLOADED狀態所以只顯示 lodaing 下面的 error
        // 和empty暂时不显示
        if (null != mLoadingView) {
            mLoadingView.setVisibility(mState == STATE_UNLOADED
                    || mState == STATE_LOADING ? View.VISIBLE :

            View.INVISIBLE);
        }
        if (null != mErrorView) {
            mErrorView.setVisibility(mState == STATE_ERROR ? View.VISIBLE
                    : View.INVISIBLE);
        }
        if (null != mEmptyView) {
            mEmptyView.setVisibility(mState == STATE_EMPTY ? View.VISIBLE
                    : View.INVISIBLE);
        }

        if (mState == STATE_SUCCEED && mSucceedView == null) {
            mSucceedView = createSuccessView();
            addView(mSucceedView, new LayoutParams

            (LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        }
        if (null != mSucceedView) {
            mSucceedView.setVisibility(mState == STATE_SUCCEED ?

            View.VISIBLE : View.INVISIBLE);
        }
    }
    public void show() {
        // 第一次进来肯定要 转圈的 所以就算是 error和empty 也要让状态是 unload
        if (mState == STATE_ERROR || mState == STATE_EMPTY) {
            mState = STATE_UNLOADED;
        }
        // 如果是unload 就把状态 变为 loading了 这时候从服务器拿数据
        if (mState == STATE_UNLOADED) {
            mState = STATE_LOADING;

            TaskRunnable task = new TaskRunnable();
            ThreadManager.getLongPool().execute(task);
        }
        showSafePagerView();
    }
    /**
     * 制作界面
     *
     * @return
     */
    protected abstract View createSuccessView();

    /**
     * 处理下载 耗时操作
     *
     * @return
     */
    protected abstract LoadResult load();

    /**
     * 空界面
     *
     * @return
     */
    public View createEmptyView() {
        if (loadpage_empty != 0) {
            return UIUtils.inflate(loadpage_empty);
        }
        return null;

    }

    /**
     * 失败的页面
     *
     * @return
     */
    public View createErrorView() {
        if (loadpage_empty != 0) {
            return UIUtils.inflate(loadpage_error);
        }
        return null;
    }

    /**
     * 正在旋转的页面
     *
     * @return
     */
    public View createLoadingView() {
        if (loadpage_empty != 0) {
            return UIUtils.inflate(loadpage_loading);
        }
        return null;
    }

    class TaskRunnable implements Runnable {
        @Override
        public void run() {
            final LoadResult loadResult = load();
            SystemClock.sleep(500);
            UIUtils.runInMainThread(new Runnable() {
                @Override
                public void run() {
                    mState = loadResult.getValue();
                    showPagerView();
                }
            });
        }
    }
    public enum LoadResult {
        ERROR(3), EMPTY(4), SUCCESS(5);
        int value;

        LoadResult(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }
}

下面是如何使用了

package com.wang.cn.base;

import com.example.every_text.view.LoadingPager;
import com.example.every_text.view.LoadingPager.LoadResult;
import com.wang.cn.R;
import com.wang.cn.utils.UIUtils;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

/**
 * @author wang
 * @version 创建时间:2015年7月8日 上午11:31:11 类说明 activity的基类
 */
public abstract class BaseActivity extends Activity {
    public LoadingPager loadingPage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        loadingPage = new LoadingPager(UIUtils.getContext(),
                R.layout.loadpage_loading, R.layout.loadpage_error,
                R.layout.loadpage_empty)//加载了三个页面
        {
            @Override
            protected LoadResult load() {
                return BaseActivity.this.load();//传递给子类
            }
            @Override
            protected View createSuccessView() {
                return BaseActivity.this.createSuccessView();//传递给子类
            }
        };
//      可以点击
        loadingPage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                loadingPage.show();
            }
        });
//      显示 loading的页面
        loadingPage.show();
        setContentView(loadingPage);
    }

    /**
     * 刷新页面工程
     *
     * @return
     */
    protected abstract View createSuccessView();

    /**
     * 请求服务器 获取当前状态
     *
     */
    protected abstract LoadResult load();

}

逼格的来了 基类调用父类怎样呢

package com.wang.cn;

import android.content.Intent;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

import com.example.every_text.view.LoadingPager.LoadResult;
import com.wang.cn.base.BaseActivity;
import com.wang.cn.utils.UIUtils;
import com.wang.cn.utils.ViewUtils;

/**
 * @author wang
 * @version 创建时间:2015年7月8日 上午11:31:11 类说明 主函数
 */
public class MainActivity extends BaseActivity {
    // 刷新页面工程
    @Override
    protected View createSuccessView() {
        View inflate = UIUtils.inflate(R.layout.activity_main);

        TextView tv=ViewUtils.findViewById(inflate, R.id.textView1);
        tv.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent=new Intent(UIUtils.getContext(),FragmetActivity.class);
                startActivity(intent);
            }
        });
        return inflate;
    }

    // 刷新页面工程
    @Override
    protected LoadResult load() {
        SystemClock.sleep(2000);
        return LoadResult.SUCCESS;
    }
}

怎么样,开始我们说的 加载数据 和显示代码 都搞定了。再也不用因为 写loading儿烦恼了吧。也不用因为 handler获取到好多msg儿烦恼在哪里加了。

代码下载地址:http://download.csdn.net/detail/wanghao200906/8880719(有我使用多年的工具类)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-06 11:58:43

高效抽取loading,再多的加载页面也不怕的相关文章

cocos2d-x 3.3 之卡牌设计 NO.6 Loading界面(异步加载图片,plist)

刚开始做卡牌的时候没有想到要做loading,因为小游戏资源不多. 但是后来不断的加图片,直到在真机上发现卡顿的问题,我才知道该需要加loading了...... 首先,我们先定义类: class Loading : public Layer { public: bool init(); CREATE_FUNC( Loading); static Scene* CreateScene(); int total_pic_num;//需加载图片数 int total_sound_num;//需加载声

爬虫再探实战(三)———爬取动态加载页面——selenium

自学python爬虫也快半年了,在目前看来,我面临着三个待解决的爬虫技术方面的问题:动态加载,多线程并发抓取,模拟登陆.目前正在不断学习相关知识.下面简单写一下用selenium处理动态加载页面相关的知识.目标——抓取页面所有的高考录取分数信息. 对于动态加载,开始的时候是看到Selenium+Phantomjs的强大,直接就学的这个.打开网页查看网页源码(注意不是检查元素)会发现要爬取的信息并不在源码里面.也就是说,从网页源码无法通过解析得到数据.Selenium+Phantomjs的强大一方

easyui的tab加载页面中的form重复提交

http://blog.csdn.net/fxz1982/article/details/8987769 Easyui中的tabs组件以href方式加载目标页面,如果目标页面中有dialog或者window这类的easyui组件中放了form.那么在关闭这个tab再次打开.如果进行form提交操作,后台就会收到两次提交请求,再次重复以上操作会收到3次提交请求,如果将表单serialize()后以jquery的post提交服务器将收到值全是数组方式组织的. 经分析发现,Easyui的tab加载页面

屏蔽电信流氓广告造成的诡异的问题--Android WebView 长时间不能加载页面

发现在家里的时候用Android App里的WebView打开网站很慢,会有十几秒甚至更长时间的卡住. 但是在电脑上打开同样的网页却很快. 查找这个问题的过程比较曲折,记录下来. 抓取Android网络数据 为了调试这个问题,首先要抓取Android的网络包数据.开始时,是想用Wireshark来抓包的,但是很麻烦,tcpdump在手机要root权限. 于是转换思路,能不能在Android上设置代理,来抓包? 但是fiddler没有linux版本,于是转用BurpSuite了. 设置Androi

artdialog 异步加载页面 生成验证码

artdialog  异步加载一个页面 需求:例如现在好多网站的登录或注册 都是点击弹出一个层出来 然后在上面登录.注册 这个登录可能在网站的每个页面都会有,但是我们又不能在每个页面都这一段html加载出来不显示,到需要用的时候,在给shou出来,这样做于情于理都说!不!!过!!!去!!!!!! 恰好以前接触过artdialog  不多说上代码,(注意思维,代码是死的方法是活,解决需求不一定非要这个方法 ) 1.页面html代码 1 <head runat="server">

加载页面遮挡耗时操作任务页面--第三方开源--AndroidProgressLayout

在Android的开发中,往往有这种需求,比如一个耗时的操作,联网获取网络图片.内容,数据库耗时读写等等,在此耗时操作过程中,开发者也许不希望用户再进行其他操作(其他操作可能会引起逻辑混乱),而此时需要给用户一个额外的加载页面遮挡住主逻辑代码的运行,待主页面的耗时操作完成后,自动消失这样加载过度页面,恢复出正常应该显示的页面. 举个实际的例子,如代码使用Android WebView打开一个网页链接试图加载某个网站,但网络质量不佳,需要耗时很久,那么在这个过程中,较好的用户体验做法是:给用户一个

Ajax滚动加载页面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title>  <m

VS2015 Cordova实现WebView加载页面进度条(Android)

因为使用Cordova做app时,加载页面没有进度条,用户无法感知打开进度,故加入进度条,具体实现如下: 1.  如果项目没有生成过apk,需先生成一次,这样在项目下面才会出现platforms/android的文件夹. 2.  进入项目/platforms/android/src文件夹下,在你程序包名目录下找到你的MainActivity.java文件,增加一个Dialog和ProgressBar用来显示页面加载进度,具体代码实现如下: 1 /* 2 Licensed to the Apach

PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题

PageSlider中CSS3动画在除首屏之外先加载页面后执行动画的问题,PageSlider中加入CSS3动画的话,默认只有首屏是从无到有执行动画,其他屏都是显示下页面再执行动画 这就造成其他屏的动画展示效果不好,解决方法,让所有屏的背景可见,但是只要当前屏的元素可见; 上代码: .page { width: 100%; height: 100%; -webkit-backface-visibility: hidden; -webkit-perspective: 1000; div, ul,