LoadingView解决首次页面刷新状态(请求中,无数据,失败)

来源:互联网 发布:银行卡校验规则 js 编辑:程序博客网 时间:2024/06/04 18:19

引言

1.我们在日常开发中经常会遇到数据加载需要网络请求的场景,我们通常的做法是用系统提供的ProgressDialog组件(显示等待进度的dialog) 但是会有一个不友好的地方(假如网络出异常了,此时页面没有填充数据。此时就要控制页面 内一些交互操作,这样界面中就会多出一大串逻辑控制代码),有一种解决方案解决上述的缺点,就是界面内部用一个进度条 遮盖内容页面,用逻辑进行控制请求中、请求失败、无数据等几种状态,但是一个app里面有辣么多的界面都是这种需求, 要是每个界面都这样写岂不很重复繁琐。如何简化呢,封装起来(*@ο@*) 哇~2.今天给大家介绍个自定义view组件来解决此问题(ui的效果根据大家自己的需求 自行定制哈)

先来张动态图=-=
这里写图片描述

需求点

1.这个view需要有一个方法来控制各个状态的切换2.可以定制加载进度条的状态3.可以定制无数据的页面4.加载失败可以提供刷新操作

实现思路

既然是自定义view,api就得尽量简洁好理解嘛,我所设想的api
//根据场景切换各个状态State各种状态的枚举(往下看)public void notifyDataChanged(State state)//数据加载失败提供重试的回调public void setOnRetryListener(OnRetryListener listener)//设置数据为null显示的viewpublic void setEmptyView(View view)//重试回调的接口0public interface OnRetryListener {        void onRetry();}

刷新的各种状态

public enum State {        ing, error, done, empty}

api是不是很简单^_^
接下来贴整个类的代码(一种不到100行代码)

package cn.wei.library.widget;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.widget.FrameLayout;import cn.wei.library.R;/** * LoadingView解决了请求网络数据时ui显示的三种状态 * 分别为加载中,加载失败,无数据 * email: qinwei_it@163.com * @author qinwei create by 2015/10/28 */public class LoadingView extends FrameLayout implements OnClickListener {    private View empty;    private View error;    private View loading;    private State state;    private OnRetryListener listener;    public interface OnRetryListener {        void onRetry();    }    public enum State {        ing, error, done, empty    }    public LoadingView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initializeView(context);    }    public LoadingView(Context context, AttributeSet attrs) {        super(context, attrs);        initializeView(context);    }    public LoadingView(Context context) {        super(context);        initializeView(context);    }    private void initializeView(Context context) {        LayoutInflater.from(context).inflate(R.layout.widget_loading_view, this);        empty = findViewById(R.id.empty);        loading = findViewById(R.id.loading);        error = findViewById(R.id.error);        setOnClickListener(this);        notifyDataChanged(State.ing);    }    public void notifyDataChanged(State state) {        this.state = state;        switch (state) {            case ing:                setVisibility(View.VISIBLE);                loading.setVisibility(View.VISIBLE);                empty.setVisibility(View.GONE);                error.setVisibility(View.GONE);                break;            case empty:                setVisibility(View.VISIBLE);                loading.setVisibility(View.GONE);                empty.setVisibility(View.VISIBLE);                error.setVisibility(View.GONE);                break;            case error:                setVisibility(View.VISIBLE);                loading.setVisibility(View.GONE);                empty.setVisibility(View.GONE);                error.setVisibility(View.VISIBLE);                break;            case done:                setVisibility(View.GONE);                break;            default:                break;        }    }    public void setOnRetryListener(OnRetryListener listener) {        this.listener = listener;    }    public void setEmptyView(View view) {        empty.removeAllViews();        empty.addView(view);    }    @Override    public void onClick(View v) {        if (listener != null && state == State.error) {            listener.onRetry();        }    }}

widget_loading_view.xml布局:

<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <LinearLayout        android:id="@+id/empty"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:orientation="vertical"        android:visibility="gone">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="无数据" />    </LinearLayout>    <LinearLayout        android:id="@+id/loading"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:orientation="vertical">        <!---mWidgetContainerView-->        <ProgressBar            android:id="@+id/progressBar"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />    </LinearLayout>    <LinearLayout        android:id="@+id/error"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:orientation="vertical"        android:visibility="gone">        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/ic_load_err" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginTop="8dp"            android:text="网络出问题啦"            android:textColor="#8e9fa5"            android:textSize="12sp" />        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginTop="8dp"            android:text="点击屏幕,重新加载"            android:textColor="#8e9fa5" />    </LinearLayout></merge>

LoadingView如何使用呢
1.xml布局引入LoadingView

<cn.wei.library.widget.LoadingView android:id="@+id/mLoadingView" android:layout_width="match_parent" android:layout_height="match_parent" />

2.activity或者fragment里面

import android.view.Menu;import android.view.MenuItem;import android.widget.ViewSwitcher;import cn.wei.library.widget.EmptyView;import cn.wei.weilibrary.R;import cn.wei.weilibrary.base.BaseTitleActivity;public class EmptyViewActivity extends BaseActivity implements EmptyView.OnRetryListener {    private ViewSwitcher mViewSwitcher;    private EmptyView mEmptyView;    @Override    protected void setContentView() {        setContentView(R.layout.activity_empty_view);    }    @Override    protected void initializeData() {        setTitle("EmptyView");        mLoadingView= (LoadingView) findViewById(R.id.mEmptyView);        mLoadingView.setOnRetryListener(this);        mLoadingView.notifyDataChanged(LoadingView.State.ing);    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.menu_emtyp_view, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId()) {            case R.id.action_nodata:                mLoadingView.notifyDataChanged(LoadingView.State.empty);                break;            case R.id.action_loading:                mLoadingView.notifyDataChanged(LoadingView.State.ing);                break;            case R.id.action_err:                mLoadingView.notifyDataChanged(LoadingView.State.error);                break;            default:                break;        }        return super.onOptionsItemSelected(item);    }    @Override    public void onRetry() {        mLoadingView.notifyDataChanged(LoadingView.State.ing);    }}

嘿嘿还差个BaseActivity基类(关于在base类的讲解,以后单独出一篇文章解释)给大家补上

import android.os.Bundle;import android.support.v7.app.AppCompatActivity;/** * 结构化activity的代码 * 方法调用顺序为setContentView()->initializeView()-> initializeData(); */public abstract class BaseActivity extends AppCompatActivity {    protected String TAG = this.getClass().getSimpleName();    @Override    protected void onCreate(Bundle saveInstance) {        super.onCreate(saveInstance);        setContentView();        initializeView();        initializeData();    }    @Override    protected void onStart() {        super.onStart();    }    @Override    protected void onResume() {        super.onResume();    }    @Override    protected void onPause() {        super.onPause();    }    @Override    protected void onStop() {        super.onStop();    }    @Override    protected void onDestroy() {        super.onDestroy();    }    /**     * 1. 设置布局     */    protected abstract void setContentView();    /**     * 2. 初始化布局     */    protected abstract void initializeView();    /**     * 3. 初始化ui数据     */    protected abstract void initializeData();}

是不是很简单呢,需要源码的同学可以加qq群139402565

结束语

最近才开始写博客,如果文章里有什么不对的地方还请大家斧正!
1 0
原创粉丝点击