1. 概述与分析
在实际项目中,我们不可避免的需要网络请求数据,由于网络或请求方式等主观或客观原因,导致我们请求的结果有时会出现一些偏差,从而导致我们UI界面显示也会有所不同。一般情况下,网络请求后我们的界面一般呈现三种页面状态:“正在加载中”、“加载失败”和“加载成功”。那么就可以通过网络请求后结果让UI界面自动切换,
2. 设计思路
通常情况下,正在加载和加载失败的界面都是相同的,只有加载成功后的界面不同。为了能让UI界面随着网络请求结果自动切换,那我们可以按照如下思路去设计:
1: 将三种状态的界面叠加在一起
2: 定义三种状态
3: 定义一个当前状态
4: 定义一个根据当前状态来切换界面的方法
5: 定义一个根据网络请求返回结果自动切换界面的方法
综上分析,我们可以得出如下框架原理图:
3. 代码实现
原理上面已经分析清楚了,下面我们就将原理用代码来实现:
/**
* author:salmonzhang
* Description:UI切换框架
* Date:2017/8/6 0018 10:05
*/
public abstract class LoadPager extends FrameLayout {
private View mLoadingView;
private View mSuccessView;
private View mErrorView;
public LoadPager(@NonNull Context context) {
this(context, null);
}
public LoadPager(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public LoadPager(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//初始化UI框架三个界面
private void init() {
//正在加载界面
if (mLoadingView == null) {
//此处正在加载界面的布局需要手动加入
mLoadingView = View.inflate(getContext(), R.layout.page_loading, null);
}
//加载成功界面
if (mSuccessView == null) {
//成功的布局谁用谁传
mSuccessView = createSuccessView();
if (mSuccessView == null) {
throw new RuntimeException("亲,请添加一个布局");
}
}
//加载失败的界面
if (mErrorView == null) {
//此处加载失败界面的布局需要手动加入
mErrorView = View.inflate(getContext(), R.layout.page_error, null);
}
//将三个布局添加在一起
addView(mLoadingView);
addView(mSuccessView);
addView(mErrorView);
//页面切换的方法
changeView();
//根据网络数据,自动切换页面
autoShowPager();
}
//自动切换页面
private void autoShowPager() {
new Thread(new Runnable() {
@Override
public void run() {
//获取网络数据
Object obj = getNetData();
//校验数据,根据返回状态自动切换状态
mCurrentState = checkData(obj);
//主线程去修改界面(注:这里我调用的是我工具类中的runOnUIThread方法)
Utils.runOnUIThread(new Runnable() {
@Override
public void run() {
changeView();
}
});
}
}).start();
}
//校验数据
private STATE checkData(Object obj) {
if (obj == null) {//如果数据为空,则失败
return STATE.ERROR;
} else {
if (obj instanceof List) {//如果返回的是数组
List list = (List) obj;
if (list.size() > 0) {
return STATE.SUCCESS;
} else {
return STATE.ERROR;
}
} else {//如果是对象
return STATE.SUCCESS;
}
}
}
//页面切换方法
private void changeView() {
//先将三个页面都隐藏
mLoadingView.setVisibility(GONE);
mSuccessView.setVisibility(GONE);
mErrorView.setVisibility(GONE);
//根据当前状态切换
switch (mCurrentState) {
case LOADING:
mLoadingView.setVisibility(VISIBLE);
break;
case SUCCESS:
mSuccessView.setVisibility(VISIBLE);
break;
case ERROR:
mErrorView.setVisibility(VISIBLE);
break;
}
}
//定义三个状态
public enum STATE {
LOADING,//正在加载中
SUCCESS,//加载成功
ERROR;//加载失败
}
//定义一个当前状态(默认正在加载中)
private STATE mCurrentState = STATE.LOADING;
//创建一个加载成功的界面
public abstract View createSuccessView();
//请求网络数据
public abstract Object getNetData();
}
4. UI框架的使用
在开发中我们一般都会定义一个BaseFragment,当涉及到网络请求数据时,此时就可以在onCreateView方法中使用UI自动切换框架来加载布局。示例代码如下:
public abstract class BaseFragment extends Fragment {
public LoadPager mLoadPager;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//使用UI自动切换框架加载页面
if (mLoadPager == null) {
mLoadPager = new LoadPager(getContext()) {
@Override
public Object getNetData() {
return questData();
}
@Override
public View createSuccessView() {
return createItemView();
}
};
}
return mLoadPager;
}
//子类创建布局
public abstract View createItemView();
//子类实现数据请求
public abstract Object questData();
}
好了,上面就是网络请求UI自动切换框架的分析、实现和使用。希望对你有所帮助,不足之处,望指正,多谢!
原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/192815.html