Android LCE架构设计

LCE架构,按拆字法解析:L:Loading加载,C:Content加载内容,E:Error加载失败。
LCE架构使用最为常见的场景是做列表数据的加载,在加载时,如果隔壁老王占用了你的带宽,那么数据加载会变的很慢,为了不让用户觉得等待漫长,可以出现一个加载场景;当数据加载成功时,将数据显示在UI上;如果数据加载失败,可以显示一个加载失败的页面或者图片,这就是LCE的使用场景。
根据上面的需求分析,可以大概的了解到LCE需要的组成部分:动画,场景体现(不同场景的UI显示)。动画主要在三个方便体现:加载中,加载成功,加载失败。场景体现主要有五个方面的体现:显示loading,显示数据内容,显示加载失败,加载数据和绑定数据。那么久先来定义两个接口:
动画接口:

public interface ILceAnimator {void showLoading(View loadingView, View contentView, View errorView);void showErrorView(View loadingView, View contentView, View errorView);void showContent(View loadingView, View contentView, View errorView);
}

场景接口:

public interface LceView<M> extends IView {/*** 显示loading页面 pullToRefresh:true代表你用的是下拉刷新组件* * @param pullToRefresh*/void showLoading(boolean pullToRefresh);/*** 显示ContentView*/void showContent();/*** 显示异常界面*/void showError();/*** 绑定数据* * @param data*/void bindData(M data);/*** 加载数据** @param pullToRefresh*/void loadData(boolean pullToRefresh);}

为了方便使用,可以提供一个默认的动画和场景实现。
默认的LCE场景实现:

public class LceViewImpl<M> implements LceView<M> {private View loadingView;private View contentView;private View errorView;private ILceAnimator lceAnimator;/*** 初始化视图* * @param v*/public void initLceView(View v) {if (loadingView == null) {loadingView = v.findViewById(R.id.loadingView);}if (contentView == null) {contentView = v.findViewById(R.id.contentView);}if (errorView == null) {errorView = v.findViewById(R.id.errorView);}if (loadingView == null) {throw new NullPointerException("loadingView is not null!");}if (contentView == null) {throw new NullPointerException("contentView is not null!");}if (errorView == null) {throw new NullPointerException("errorView is not null!");}}/*** 添加重写加载监听* * @param onClickListener*/public void setOnErrorViewClickListener(OnClickListener onClickListener) {if (this.errorView != null) {this.errorView.setOnClickListener(onClickListener);}}private ILceAnimator getLceAnimator() {if (lceAnimator == null) {lceAnimator = DefaultLceAnimator.getInstance();}return lceAnimator;}/*** 绑定动画执行策略* * @param lceAnimator*/public void setLceAnimator(ILceAnimator lceAnimator) {this.lceAnimator = lceAnimator;}/*** 注意:记得加判断,因为下拉刷新组件有正在加载头部视图,不需要显示加载过程了* @param pullToRefresh*/@Overridepublic void showLoading(boolean pullToRefresh) {if(!pullToRefresh){getLceAnimator().showLoading(loadingView, contentView, errorView);}}@Overridepublic void showContent() {getLceAnimator().showContent(loadingView, contentView, errorView);}@Overridepublic void showError() {getLceAnimator().showErrorView(loadingView, contentView, errorView);}@Overridepublic void bindData(M data) {}@Overridepublic void loadData(boolean pullToRefresh) {}}

默认的动画实现:

@SuppressLint("NewApi")
public class DefaultLceAnimator implements ILceAnimator {private volatile static DefaultLceAnimator lceAnimator;public DefaultLceAnimator() {}public static DefaultLceAnimator getInstance() {if (lceAnimator == null) {synchronized (AnimatorUtils.class) {if (lceAnimator == null) {lceAnimator = new DefaultLceAnimator();}}}return lceAnimator;}@Overridepublic void showLoading(View loadingView, View contentView, View errorView) {contentView.setVisibility(View.GONE);errorView.setVisibility(View.GONE);loadingView.setVisibility(View.VISIBLE);}@Overridepublic void showErrorView(final View loadingView,final View contentView,final View errorView) {contentView.setVisibility(View.GONE);final Resources resources = loadingView.getResources();// Not visible yet, so animate the view inAnimatorSet set = new AnimatorSet();ObjectAnimator in = ObjectAnimator.ofFloat(errorView, "alpha", 1f);ObjectAnimator loadingOut = ObjectAnimator.ofFloat(loadingView,"alpha", 0f);set.playTogether(in, loadingOut);set.setDuration(resources.getInteger(R.integer.lce_error_view_show_animation_time));set.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {super.onAnimationStart(animation);errorView.setVisibility(View.VISIBLE);}@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);loadingView.setVisibility(View.GONE);loadingView.setAlpha(1f); // For future showLoading calls}});set.start();}@Overridepublic void showContent(final View loadingView,final View contentView,final View errorView) {if (contentView.getVisibility() == View.VISIBLE) {errorView.setVisibility(View.GONE);loadingView.setVisibility(View.GONE);} else {errorView.setVisibility(View.GONE);final Resources resources = loadingView.getResources();final int translateInPixels = resources.getDimensionPixelSize(R.dimen.lce_content_view_animation_translate_y);// Not visible yet, so animate the view inAnimatorSet set = new AnimatorSet();ObjectAnimator contentFadeIn = ObjectAnimator.ofFloat(contentView,"alpha", 0f, 1f);ObjectAnimator contentTranslateIn = ObjectAnimator.ofFloat(contentView, "translationY", translateInPixels, 0);ObjectAnimator loadingFadeOut = ObjectAnimator.ofFloat(loadingView,"alpha", 1f, 0f);ObjectAnimator loadingTranslateOut = ObjectAnimator.ofFloat(loadingView, "translationY", 0, -translateInPixels);set.playTogether(contentFadeIn, contentTranslateIn, loadingFadeOut,loadingTranslateOut);set.setDuration(resources.getInteger(R.integer.lce_content_view_show_animation_time));set.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {contentView.setTranslationY(0);loadingView.setTranslationY(0);contentView.setVisibility(View.VISIBLE);}@Overridepublic void onAnimationEnd(Animator animation) {loadingView.setVisibility(View.GONE);loadingView.setAlpha(1f); // For future showLoading callscontentView.setTranslationY(0);loadingView.setTranslationY(0);}});set.start();}}}

在集成LCE的时候,如果没有提供自定的实现,那么就是用默认的实现。
Fragment LCE集成实现:

public abstract class LceFragment<M> extends Fragment implements LceView<M> {// 初始化Lce UI布局(规定你的Lce布局文件的id)private LceViewImpl<M> lceViewImpl;@Overridepublic void onViewCreated(View view, Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);if (lceViewImpl == null) {lceViewImpl = new MvpLceViewImpl<M>();}initLceView(view);}private void initLceView(View v) {lceViewImpl.initLceView(v);lceViewImpl.setOnErrorViewClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {onErrorClick();}});}public void setLceAnimator(ILceAnimator lceAnimator){lceViewImpl.setLceAnimator(lceAnimator);}@Overridepublic void showLoading(boolean pullToRefresh) {lceViewImpl.showLoading(pullToRefresh);}@Overridepublic void showContent() {lceViewImpl.showContent();}@Overridepublic void showError() {lceViewImpl.showError();}@Overridepublic void loadData(boolean pullToRefresh) {lceViewImpl.loadData(pullToRefresh);}@Overridepublic void bindData(M data) {lceViewImpl.bindData(data);}public void onErrorClick() {loadData(false);}}

当然也可以将LCE集成到Activity中。

Android LCE架构设计相关推荐

  1. android客户端框架,最新的一版,通用Android 客户端架构设计,只有你还没看过

    客户端架构设计 客户端设计 目的是整体设计客户端App,架构上打好铺垫. Android客户端架构设计 主要从以下几个方面进行设计:MVP设计风格.整体架构.日志系统.网络系统.本地存储.Test模块 ...

  2. Android APP架构设计——MVP的使用示例

    0. 前言 为了更好地进行移动端架构设计,我们最常用的就是MVC.MVP和MVVM,作为三个最耳熟能详的三大架构,应用可谓非常广泛.对于这三种架构设计以及优缺点已经在Android APP架构设计-- ...

  3. Android App 架构设计相关资料汇总

    1. 前言 只要有1,2年工作经验的程序员,多多少少都会接触到架构东西.可能平时工作中不一定会有机会从0到1完完全全自己去设计一套架构出来,但是如果想成为高级工程师,技术专家,架构师--尽早接触架构方 ...

  4. 一种Android客户端架构设计分享

    转载请注明出处:http://blog.csdn.net/ahence/article/details/56678126 技术发展日新月异,业界各种Android客户端架构设计,五花八门,但我们不能简 ...

  5. 浅谈一种Android客户端架构设计

    技术发展日新月异,业界各种Android客户端架构设计,五花八门,但我们不能简单地说哪种架构更好,因为脱离业务谈架构是没有任何意义的,适合业务的才是好架构.而架构也不是一成不变的,随着业务的发展,也许 ...

  6. Android项目架构设计深入浅出

    简介:本文结合个人在架构设计上的思考和理解,介绍如何从0到1设计一个大型Android项目架构. 作者 | 璞珂 来源 | 阿里技术公众号 前言:本文结合个人在架构设计上的思考和理解,介绍如何从0到1 ...

  7. Android 项目架构设计深入浅出

    前言:本文结合个人在架构设计上的思考和理解,介绍如何从0到1设计一个大型Android项目架构. 一 引导 本文篇幅较长,可结合下表引导快速了解全文主脉络. 二 项目架构演进 该章节主要对一个Andr ...

  8. Android 软件平台架构设计

    试想你做的不是一个软件,  而是一个软件族, 这个些软件需要在Android平台发布, 你应该做何种规划?  这些问题需要在以下真实场景中考虑: QQ发布的特有手机, 需要继承多个软件: QQ空间.股 ...

  9. Android App架构设计

    前言 Web的架构经过多年的发展已经非常成熟了,我们常用的SSM,SSH等等,架构都非常标准.个人认为,Web服务逻辑比较清晰,目的明确,流程也相对固定,从服务器收到请求开始,经过一系列的的拦截器,过 ...

最新文章

  1. 【tyvj1052】【树状dp】没有上司的舞会
  2. 程序员必须知道的几个Git代码托管平台(转)
  3. 基于eureka如何使用spring cloud zuul 网关
  4. 如何让服务器端持续监听客户端的请求?
  5. [ZJOI2007]报表统计(链表法+set)
  6. 细粒度图像分类_1.1、 图片分类
  7. xmlhttp status各类Http请求状态(status)及其含义
  8. for 循环 与forEach 里面return 的区别
  9. [React Native]StatusBar的使用
  10. 算法: 用队列Queue实现栈Stack
  11. 中国麻将:世界上最早的区块链项目
  12. Win系统使用WSL子系统Linux启动vGPU增强图形性能加速OpenGL
  13. Word文档生成神器:开源项目poi.tl使用介绍
  14. 拿到offer后,我死死的抓着他们不放
  15. 云服务器是怎么虚拟的,云服务器怎么虚拟化
  16. 触摸屏坏了有哪些现象_触摸屏常见的故障及解决方法(实用)
  17. 可怕的乖孩子_你知道乖孩子的一生,有多可怕吗?
  18. 基于opentx开源软件,DIY属于自己的uav遥控器
  19. 【题解】LuoGu4610:[COI2012] KAMPANJA
  20. Java程序猿搬砖笔记(七)

热门文章

  1. 坚定融合网络 Qlogic心态开放广结伙伴
  2. 伤寒杂病论.辨少阴病脉证并治
  3. 小风扇上日本亚马逊需要做什么认证
  4. Docker从无到有
  5. 零束科技获得中国信通院“2022 XOps产业生态峰会优秀案例”奖
  6. 海外拥有最庞大社区人群的Verasity($VRA),后市值得期待
  7. 【论文译文】Generative Image Inpainting with Contextual Attention
  8. 浅析STM32 Bootloader设计
  9. 干货分享!BMS电池管理系统主动均衡设计案例
  10. 统计学及统计学在MATLAB的应用