登录 立即注册
安币:

查看: 7264|回复: 24

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

[复制链接]

57

主题

59

帖子

124

安币

程序猿

Rank: 2

发表于 2015-7-15 10:26:09 | 显示全部楼层 |阅读模式

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

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

下面是页面多的时候状态

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


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

一般页面有四种情况

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

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

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

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

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

先屡一下思路

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

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

3 数据可用显示 成功界面

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

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

下面直接上代码时间:

[Java] 查看源文件 复制代码
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;
    }
  }
}

下面是如何使用了

[Java] 查看源文件 复制代码
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();
}

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

[Java] 查看源文件 复制代码
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 (有我使用多年的工具类)


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

0

主题

0

帖子

0

安币

初级码农

Rank: 1

发表于 2015-7-15 16:33:26 | 显示全部楼层
加载数据的网络请求在哪里写呢?网络请求是个延时操作,在load()里如何完成呢

0

主题

123

帖子

196

安币

程序猿

Rank: 2

QQ达人

发表于 2015-7-15 18:07:06 | 显示全部楼层
有点感觉~~~~~~~~~~

0

主题

0

帖子

-15

安币

限制会员

发表于 2015-7-26 02:18:55 | 显示全部楼层
学习了!!!!

0

主题

0

帖子

-2

安币

限制会员

发表于 2015-8-5 10:30:44 | 显示全部楼层
还是看不懂,复杂

0

主题

0

帖子

-11

安币

限制会员

发表于 2015-8-22 12:06:56 | 显示全部楼层
这个不错,谢谢共享

0

主题

0

帖子

-6

安币

限制会员

发表于 2015-9-8 13:43:08 | 显示全部楼层
很不错的哦,支持,加油

0

主题

0

帖子

-8

安币

限制会员

发表于 2015-9-29 01:40:56 | 显示全部楼层
谢谢楼主,,,收藏ing
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区

联系我们
关闭
合作电话:
15618560077
Email:
805941275@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

快速回复 返回顶部 返回列表