android客户端界面加载处理方法
来源:互联网 发布:数控火焰切割编程代码 编辑:程序博客网 时间:2024/06/05 04:52
Knowledge is a treasure but practice is the key to it.
在android的前端开发过程中,对于前端的加载效果,界面友好是很重要的。
需要在界面加载过程中的变化中友好的显示:
1:加载中
2:加载成功
3:加载失败
4:网络异常
5:请求数据接口暂时没有数据
etc,所以,需要我们自己书写相关的界面加载类,来做一个统一的整理
在刚开始遇到这样的问题时,就个人而言,用的最笨的办法也是最耗性能。在原有的正常UI界面中添加 include 标签,然后根据逻辑进行隐藏显示。很不自在。之后在优化中总结经验,创建自己的界面类。
正题:
step1:自定义View extends FrameLayout
step2:创建enum来确定相应的状态
step3:创建相应界面的layout
package com.welive.defineview;import ···/*** author:wedfrend* email:wedfrend@yeah.net* create:2017/8/29 11:11* desc: 在手机端加载过程中,会出现很多的状况 * * 1:加载中 * 2:数据出错 * 3:网络异常 * 4:重新加载 * * 为了方便的统一管理,所以自定义View来进行相应的加载状态方法 **/public class NavFrameLayout extends FrameLayout { private FrameLayout wholeFrameLayout; //布局中的子页面 private View mContentView; private LayoutInflater layoutInflater; //不同的状态 private View statusView; private EnumContent.statusPage statusPage = EnumContent.statusPage.LOADING; public EnumContent.statusPage getStatusPage() { return statusPage; } public void setStatusPage(EnumContent.statusPage statusPage) { this.statusPage = statusPage; }/*** 默认情况下的三种布局界面*/ private final int loadingLayoutId = R.layout.z_loading_layout;//加载中 private final int dateErrorLayoutId = R.layout.z_daterror_layout;//数据异常 private final int netErrorLayoutId = R.layout.z_neterror_layout;//网络异常 public NavFrameLayout(Context context) { super(context,null); } public NavFrameLayout(Context context, AttributeSet attrs) { this(context, attrs,0); } public NavFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); InitDefault(context, attrs, defStyleAttr); } //初始化 public void InitDefault(Context context, AttributeSet attrs, int defStyleAttr){ wholeFrameLayout = new FrameLayout(context); layoutInflater = LayoutInflater.from(context); wholeFrameLayout.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); //该方法可以在父类中查看,是直接将该布局放置在子布局的第一个位置 addView(wholeFrameLayout); //加载界面的显示 setViewLoading(loadingLayoutId); }/**进行界面的判断,在layout下该自定义VIEW下必须有且只有一个子布局Ui,但是实际上我们在代码中添加一个View,layout中一个,所以判断必须为2*/ @Override protected void onFinishInflate() { super.onFinishInflate(); if(getChildCount() != 2){ //抛出运行时异常 throw new RuntimeException(NavFrameLayout.class.getSimpleName() + "必须有且只有一个子控件"); } mContentView = getChildAt(1); //完成之后将该View先进行隐藏 mContentView.setVisibility(View.GONE); } /** * 正在加载 * @param layoutResID */ protected SwipeRefreshLayout swipeRefreshLayout; public void setViewLoading(@LayoutRes int layoutResID){ //赋值状态 statusPage = EnumContent.statusPage.LOADING; //判断是否statusView是否已经存在,存在的话先做一次清除,因为没有必要一直存在 if (statusView != null && statusView.getParent() != null) { ViewGroup parent = (ViewGroup) statusView.getParent(); parent.removeView(statusView); } //接下来做自己界面流程 statusView = layoutInflater.inflate(layoutResID,null); if (statusView != null) { statusView.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); wholeFrameLayout.addView(statusView); } statusView.setVisibility(View.VISIBLE); swipeRefreshLayout = ((SwipeRefreshLayout) statusView.findViewById(R.id.refresh_loading)); swipeRefreshLayout.setProgressViewOffset(true, 50, 100); //设置下拉圆圈的大小,两个值 LARGE, DEFAULT swipeRefreshLayout.setSize(SwipeRefreshLayout.DEFAULT); //下拉刷新调用的一个接口 swipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary, R.color.colorPrimaryDark, R.color.colorPrimaryDarkContentActivity); //这里直接调用swipeRefrehLayout的加载状态 swipeRefreshLayout.post(() -> swipeRefreshLayout.setRefreshing(true)); } /** * 设置界面正常加载的情况下,对于不同状态需要做的处理如下,在自己主逻辑程序中只需调用方法,相应的处理状态交给该方法执行 */ public void setNormal(){ if(statusView.getVisibility() == View.VISIBLE){ //异常界面隐藏 statusView.setVisibility(View.GONE); //正常界面显示 mContentView.setVisibility(View.VISIBLE); } //处理不同的情况 if(statusPage.equals(EnumContent.statusPage.NONE)){ } //正在加载中 if(statusPage.equals(EnumContent.statusPage.LOADING)){ //加载界面显示 swipeRefreshLayout.post(() -> swipeRefreshLayout.setRefreshing(false)); return; } //数据出现异常 if(statusPage.equals(EnumContent.statusPage.DATEERROR)){ return; } //网络出现异常 if(statusPage.equals(EnumContent.statusPage.NETERROR)){ return; } setStatusPage(EnumContent.statusPage.NONE); } /** * * @param status 异常状态 * @param imgId 图片ID * @param StringId 提示字段ID */ public void setException(EnumContent.statusPage status,int imgId,int StringId){ if(statusPage.equals(EnumContent.statusPage.NONE)){ T.show(R.string.NetError,0); } statusPage = status; if(statusView.getVisibility() == View.GONE){ //正常界面隐藏 mContentView.setVisibility(View.GONE); //异常界面显示 statusView.setVisibility(View.VISIBLE); } //处理不同的情况 if(status.equals(EnumContent.statusPage.NONE)){ } //正在加载中 if(status.equals(EnumContent.statusPage.LOADING)){ //加载界面显示 setViewLoading(loadingLayoutId); return; } //数据出现异常 if(status.equals(EnumContent.statusPage.DATEERROR)){ setViewDateError(dateErrorLayoutId); return; } //网络出现异常 if(status.equals(EnumContent.statusPage.NETERROR)){ setViewNetError(netErrorLayoutId); return; } } /** * 数据异常 * @param layoutResID */ public void setViewDateError(@LayoutRes int layoutResID){ if (statusView != null && statusView.getParent() != null) { ViewGroup parent = (ViewGroup) statusView.getParent(); parent.removeView(statusView); } statusView = layoutInflater.inflate(layoutResID,null); if (statusView != null) { statusView.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); wholeFrameLayout.addView(statusView); } //下面要做些事情 } /** * 网络异常 * @param layoutResID */ public void setViewNetError(@LayoutRes int layoutResID){ if (statusView != null && statusView.getParent() != null) { ViewGroup parent = (ViewGroup) statusView.getParent(); parent.removeView(statusView); } statusView = layoutInflater.inflate(layoutResID,null); if (statusView != null) { statusView.setLayoutParams(new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); wholeFrameLayout.addView(statusView); } statusView.findViewById(R.id.tv_reloading).setOnClickListener(v -> { setException(EnumContent.statusPage.LOADING,0,0); loadingListener.onLoading(); }); } //这里还需要一个接口的触发时间,来证实界面的可行性 public interface LoadingListener{ void onLoading(); } private LoadingListener loadingListener; public LoadingListener getLoadingListener() { return loadingListener; } public void setLoadingListener(LoadingListener loadingListener) { this.loadingListener = loadingListener; }}
知识要点:
1:该类中需要注意的就是一个onFinishInflate()方法的判断以及我们在原有布局中添加一个布局。
2:addView()方法调用父类的方法
/** * <p>Adds a child view. If no layout parameters are already set on the child, the * default parameters for this ViewGroup are set on the child.</p> * * <p><strong>Note:</strong> do not invoke this method from * {@link #draw(android.graphics.Canvas)}, {@link #onDraw(android.graphics.Canvas)}, * {@link #dispatchDraw(android.graphics.Canvas)} or any related method.</p> * * @param child the child view to add * * @see #generateDefaultLayoutParams() */ public void addView(View child) { addView(child, -1); }
所以此时getChildAt(int i)中,角标0表示我们添加的View,而角标为1的表示在layout中的View
3:对于各种状态的布局以及状态发生变化的时候先清空之前的内容,在加载新的界面。
由于不同公司的定制,如果将该类作为aar文件来进行引用反而会带来更加复杂的封装,所以还是由每个开发自己去写一套适用于自己公司的类更为合适。
最终在界面绘制完成,跟布局中有两个子布局
相关实践代码请在Github中进行下载:
https://github.com/wedfrendwang/NavLayout
Everyone gets tired.No one can take the pain for you. You have to go through it and grow up.
心烦事比较多,激励一下自己。希望从事编程行业的同仁们加油。
- android客户端界面加载处理方法
- 客户端界面加载优化
- Android处理延时加载的方法
- Android处理延时加载的方法
- android 监听整个界面加载完成的方法
- Android unity3d 加载界面
- android加载界面
- Android 仿美团加载界面
- android界面加载webview
- Android 客户端登录界面实现
- android 客户端 Cookie处理
- android 客户端 Cookie处理
- ASP.NET Ajax 客户端框架未能加载,Sys未定义处理方法
- android欢迎界面动画加载
- Android开发---加载h5界面
- android加载大量大图导致OOM处理方法
- ANDROID图片加载时出现OOM的一般处理方法
- 项目个别界面无法加载问题处理
- mybatis中将varchar字段类型修改为clob
- zcmu-1182(大数相减)
- SVN图标设置找回
- 用AIDL 实现service 主动发送消息给activity
- HDU2222 Keywords Search(AC自动机)
- android客户端界面加载处理方法
- 在Linux系统下,Vi命令模式和编辑模式如何切换?
- ButterCMS架构:完成数百万次调用的关键任务API
- HttpClient的基础使用
- 深度探索TLD的C++源码,多图慎入
- 微信自定义菜单开发json拼接
- 事务从集中式到分布式的转变
- 资讯网站TDK建议
- VMware 克隆多台Linux机器并配置IP的方法