您的位置:首页 > 理论基础 > 计算机网络

根据网络请求结果返回加载失败、加载为空、加载成功、加载中的自定义视图

2017-06-11 00:00 399 查看
LoadingPage继承帧布局。

init方法中先把所有布局都一次加载进去;调用showpage方法来判断最后显示那一个页面。

public abstract class LoadingPage extends FrameLayout {

public static final int STATE_UNKOWN = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_ERROR = 2;
public static final int STATE_EMPTY = 3;
public static final int STATE_SUCCESS = 4;
public int state = STATE_UNKOWN;

private View loadingView;// 加载中的界面
private View errorView;// 错误界面
private View emptyView;// 空界面
private View successView;// 加载成功的界面

public LoadingPage(Context context) {
super(context);
init();
}

public LoadingPage(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

public LoadingPage(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

private void init() {
loadingView = createLoadingView(); // 创建了加载中的界面
if (loadingView != null) {
this.addView(loadingView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
errorView = createErrorView(); // 加载错误界面
if (errorView != null) {
this.addView(errorView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
emptyView = createEmptyView(); // 加载空的界面
if (emptyView != null) {
this.addView(emptyView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
showPage();// 根据不同的状态显示不同的界面
}

// 根据不同的状态显示不同的界面
private void showPage() {
if (loadingView != null) {
loadingView.setVisibility(state == STATE_UNKOWN || state == STATE_LOADING ? View.VISIBLE : View.INVISIBLE);
}
if (errorView != null) {
errorView.setVisibility(state == STATE_ERROR ? View.VISIBLE : View.INVISIBLE);
}
if (emptyView != null) {
emptyView.setVisibility(state == STATE_EMPTY ? View.VISIBLE : View.INVISIBLE);
}
if (state == STATE_SUCCESS) {
if (successView == null) {
successView = createSuccessView();
this.addView(successView, new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
successView.setVisibility(View.VISIBLE);
} else {
if (successView != null) {
successView.setVisibility(View.INVISIBLE);
}
}
}

/* 创建了空的界面 */
private View createEmptyView() {
View view = View.inflate(UiUtils.getContext(), R.layout.loadpage_empty, null);
Button re_loading_page_bt = (Button) view.findViewById(R.id.re_loading_page_bt);
re_loading_page_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
show();
}
});

return view;
}

/* 创建了错误界面 */
private View createErrorView() {
View view = View.inflate(UiUtils.getContext(), R.layout.loadpage_error, null);
Button loading_page_bt = (Button) view.findViewById(R.id.loading_page_bt);
loading_page_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//TODO 设置网络连接,也可以直接忽略在布局中设置网络按钮

}
});
return view;
}

/* 创建加载中的界面 */
private View createLoadingView() {
View view = View.inflate(UiUtils.getContext(), R.layout.loadpage_loading, null);
return view;
}

public enum LoadResult {
error(2), empty(3), success(4);
int value;

LoadResult(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

// 根据服务器的数据 切换状态
public void show() {
if (state == STATE_ERROR || state == STATE_EMPTY) {
state = STATE_LOADING;
}
// 请求服务器 获取服务器上数据 进行判断
// 请求服务器 返回一个结果
ThreadManager.getInstance().createLongPool().execute(new Runnable() {
@Override
public void run() {
SystemClock.sleep(500);
final LoadResult result = load();
UiUtils.runOnUiThread(new Runnable() {

@Override
public void run() {
if (result != null) {
state = result.getValue();
showPage(); // 状态改变了,重新判断当前应该显示哪个界面
}
}
});
}
});
showPage();

}

/***
* 创建成功的界面
*
* @return
*/
public abstract View createSuccessView();

/**
* 请求服务器
*
* @return
*/
protected abstract LoadResult load();
}


ThreadManager.class线程池管理类

public class ThreadManager {
private ThreadManager() {
}

private static ThreadManager instance = new ThreadManager();
private ThreadPoolProxy longPool;
private ThreadPoolProxy shortPool;

public static ThreadManager getInstance() {
return instance;
}

// 联网比较耗时
// cpu的核数*2+1
public synchronized ThreadPoolProxy createLongPool() {
if (longPool == null) {
longPool = new ThreadPoolProxy(5, 5, 5000L);
}
return longPool;
}
// 操作本地文件
public synchronized ThreadPoolProxy createShortPool() {
if(shortPool==null){
shortPool = new ThreadPoolProxy(3, 3, 5000L);
}
return shortPool;
}

public class ThreadPoolProxy {
private ThreadPoolExecutor pool;
private int corePoolSize;
private int maximumPoolSize;
private long time;

public ThreadPoolProxy(int corePoolSize, int maximumPoolSize, long time) {
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.time = time;

}
/**
* 执行任务
* @param runnable
*/
public void execute(Runnable runnable) {
if (pool == null) {
// 创建线程池
/*
* 1. 线程池里面管理多少个线程2. 如果排队满了, 额外的开的线程数3. 如果线程池没有要执行的任务 存活多久4.
* 时间的单位 5 如果 线程池里管理的线程都已经用了,剩下的任务 临时存到LinkedBlockingQueue对象中 排队
*/
pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
time, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(10));
}
pool.execute(runnable); // 调用线程池 执行异步任务
}
/**
* 取消任务
* @param runnable
*/
public void cancel(Runnable runnable) {
if (pool != null && !pool.isShutdown() && !pool.isTerminated()) {
pool.remove(runnable); // 取消异步任务
}
}
}
}


UiUtils.calss其实就是确定在主线程中更新UI操作。

public class UiUtils {
/**
* 获取到字符数组
* @param tabNames  字符数组的id
*/
public static String[] getStringArray(int tabNames) {
return getResource().getStringArray(tabNames);
}

public static Resources getResource() {
return getContext().getResources();
}
public static Context getContext(){
return BaseApplication.getApplication();
}
/** dip转换px */
public static int dip2px(int dip) {
final float scale = getResource().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f);
}

/** px转换dip */

public static int px2dip(int px) {
final float scale = getResource().getDisplayMetrics().density;
return (int) (px / scale + 0.5f);
}
/**
* 把Runnable 方法提交到主线程运行
* @param runnable
*/
public static void runOnUiThread(Runnable runnable) {
// 在主线程运行
if(android.os.Process.myTid()== BaseApplication.getMainTid()){
runnable.run();
}else{
//获取handler
BaseApplication.getHandler().post(runnable);
}
}

public static View inflate(int id) {
return View.inflate(getContext(), id, null);
}

public static Drawable getDrawalbe(int id) {
return getResource().getDrawable(id);
}

public static int getDimens(int homePictureHeight) {
return (int) getResource().getDimension(homePictureHeight);
}
/**
* 延迟执行 任务
* @param run   任务
* @param time  延迟的时间
*/
public static void postDelayed(Runnable run, int time) {
BaseApplication.getHandler().postDelayed(run, time); // 调用Runable里面的run方法
}
/**
* 取消任务
* @param auToRunTask
*/
public static void cancel(Runnable auToRunTask) {
BaseApplication.getHandler().removeCallbacks(auToRunTask);
}
/**
* 可以打开activity
* @param intent
*/
public static void startActivity(Intent intent) {
// 如果不在activity里去打开activity  需要指定任务栈  需要设置标签
if(BaseActivity.activity==null){
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
}else{
BaseActivity.activity.startActivity(intent);
}
}

}


BaseApplication.class记得要在清单文件配置

public class BaseApplication extends Application {
private static BaseApplication application;
private static int mainTid;
private static Handler handler;

@Override
// 在主线程运行的
public void onCreate() {
super.onCreate();
application = this;
mainTid = android.os.Process.myTid();
handler = new Handler();
}

public static Context getApplication() {
return application;
}

public static int getMainTid() {
return mainTid;
}

public static Handler getHandler() {
return handler;
}

}


使用这个自定义布局,需要调用show()方法,才能显示。

public abstract class BaseFragment extends Fragment {

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
show();
}

private LoadingPage loadingPage;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

if (loadingPage == null) {  // 之前的frameLayout 已经记录了一个爹了  爹是之前的ViewPager
loadingPage = new LoadingPage(getActivity()){
@Override
public View createSuccessView() {
return BaseFragment.this.createSuccessView();
}
@Override
protected LoadResult load() {
return BaseFragment.this.load();
}
};
}else{
ViewUtils.removeParent(loadingPage);// 移除frameLayout之前的爹
}

return loadingPage;  //  拿到当前viewPager 添加这个framelayout
}
/***
*  创建成功的界面
* @return
*/
public  abstract View createSuccessView();
/**
* 请求服务器
* @return
*/
protected abstract LoadingPage.LoadResult load();

public void show(){
if(loadingPage!=null){
loadingPage.show();
}
}

/**校验数据 */
public LoadingPage.LoadResult checkData(List datas) {
if(datas==null){
return LoadingPage.LoadResult.error;//  请求服务器失败
}else{
if(datas.size()==0){
return LoadingPage.LoadResult.empty;  //数据为空
}else{
return LoadingPage.LoadResult.success;//请求数据成功
}
}

}
}


ViewUtils.clss

public class ViewUtils {
public static void removeParent(View v){
//  先找到爹 在通过爹去移除孩子
ViewParent parent = v.getParent();
//所有的控件 都有爹  爹一般情况下 就是ViewGoup
if(parent instanceof ViewGroup){
ViewGroup group=(ViewGroup) parent;
group.removeView(v);
}
}
}


在子类fragment中使用

public class HomeFragment extends BaseFragment {

@Override
public View createSuccessView() {
//如果有数据的话返回显示的页面
return null;
}

@Override
protected LoadingPage.LoadResult load() {

//网络请求返回数据
List datas=new ArrayList();
//最后data为网络数据或者网络状态
return checkData(datas);
//return LoadingPage.LoadResult.empty;
}
}








圆角图片背景设置

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp"></corners>
<padding
android:bottom="10dp"
android:top="10dp"></padding>
<solid
android:color="@color/colorAccent"></solid>
</shape>

背景图片选择器

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/btn_shape_pressed" />
<item  android:state_pressed="false" android:drawable="@drawable/btn_shape"  />
</selector>

上图框架主要是传智GooglePlay所用,此文只为记录,以便下次查阅。

源码下载

http://pan.baidu.com/s/1bpnJO2F
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐