在进行网络请求中,我们希望给用户一个提示,让用户知道正在加载中(就是一个loading动画)。当加载成功或者失败后,我们又能返回对应的结果给用户,让用户一目了然,知道什么原因,之后又可以进一步处理。

1、代码很简单,创建一个类继承FrameLayout

import android.content.Context;import android.util.AttributeSet;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.TextView;public class StatusViewLayout extends FrameLayout {    private View mLoadingView;    private View mErrorView;    private View mEmptyView;    private OnClickListener mOnRetryListener;    private TextView status_view_tv_error;    private TextView status_tv_empty_msg;    public StatusViewLayout(Context context) {        this(context, null);    }    public StatusViewLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public StatusViewLayout(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        setUpView();    }    private void setUpView() {        FrameLayout.LayoutParams mLayoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        mLayoutParams.gravity = Gravity.CENTER;        mLoadingView=LayoutInflater.from(getContext()).inflate(R.layout.status_view_layout_loading, null);        mErrorView = LayoutInflater.from(getContext()).inflate(R.layout.status_view_layout_error, null);        mEmptyView = LayoutInflater.from(getContext()).inflate(R.layout.status_view_layout_empty, null);        status_view_tv_error = (TextView) mErrorView.findViewById(R.id.status_view_tv_error);        status_tv_empty_msg = (TextView) mEmptyView.findViewById(R.id.status_tv_empty_msg);        addView(mLoadingView, mLayoutParams);        addView(mErrorView, mLayoutParams);        addView(mEmptyView, mLayoutParams);        mErrorView.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View view) {                if (mOnRetryListener != null) {                    showLoading();                    mOnRetryListener.onClick(view);                }            }        });        mEmptyView.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View view) {                if (mOnRetryListener != null) {                    showLoading();                    mOnRetryListener.onClick(view);                }            }        });    }    public void setOnRetryListener(OnClickListener listener) {        mOnRetryListener = listener;    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        showLoading();    }    public void showLoading() {        for (int i = 0; i < getChildCount(); i++) {            getChildAt(i).setVisibility(View.GONE);        }        mLoadingView.setVisibility(View.VISIBLE);    }    public void showError() {        for (int i = 0; i < getChildCount(); i++) {            getChildAt(i).setVisibility(View.GONE);        }        mErrorView.setVisibility(View.VISIBLE);    }    public void showError(String msg) {        showError();        status_view_tv_error.setText(msg);    }    public void showEmpty() {        for (int i = 0; i < getChildCount(); i++) {            getChildAt(i).setVisibility(View.GONE);        }        mEmptyView.setVisibility(View.VISIBLE);    }    public void showEmpty(String msg) {        showEmpty();        status_tv_empty_msg.setText(msg);    }    public void showContent() {        for (int i = 0; i < getChildCount(); i++) {            getChildAt(i).setVisibility(View.GONE);        }        getChildAt(getChildCount() - 1).setVisibility(View.VISIBLE);    }}

2、耗时加载的界面中初始化StatusViewLayout

public class MainActivity extends AppCompatActivity {    private StatusViewLayout mStatusView;    private TextView mContent;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    /**     * 初始化     */    private void initView() {        // findView        mStatusView = (StatusViewLayout) findViewById(R.id.main_status_view);        mContent = (TextView) findViewById(R.id.main_content);        // 初始化mStatusView一开始状态为loading//        mStatusView.showLoading();        mStatusView.showContent();        // 当状态为error、empty事件回调        mStatusView.setOnRetryListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                requestData();            }        });        // mContent添加点击事件        mContent.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                mStatusView.showLoading();                requestData();            }        });    }    /**     * 网络请求     */    private void requestData() {        String url = "http://gank.io/api/data/Android/50/1";        // ok-go   github:https://github.com/jeasonlzy/okhttp-OkGo        OkGo.get(url)                .tag(this)                .execute(new StringCallback() {                    @Override                    public void onSuccess(String s, Call call, Response response) {                        // 解析json                        parsingJson(s);                    }                    @Override                    public void onError(Call call, Response response, Exception e) {                        super.onError(call, response, e);                        // 异常状态                        mStatusView.showError();                    }                });    }    /**     * 解析json     *     * @param s 请求结果     */    private void parsingJson(String s) {        try {            JSONObject jsonObject = new JSONObject(s);            if (!jsonObject.getBoolean("error")) {                mStatusView.showContent();                mContent.setText(jsonObject.getJSONArray("results").get(0).toString());            } else                mStatusView.showEmpty();        } catch (JSONException e) {            e.printStackTrace();        }    }    @Override    protected void onDestroy() {        super.onDestroy();        // 取消请求        OkGo.getInstance().cancelTag(this);    }}

3、xml中,使用StatusViewLayout包裹你的content,StatusViewLayout继承的是FrameLayout,因此可以看作一个FrameLayout布局。

<?xml version="1.0" encoding="utf-8"?><com.wz.statusviewdemo.StatusViewLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/main_status_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.wz.statusviewdemo.MainActivity">    <TextView        android:id="@+id/main_content"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!"/>com.wz.statusviewdemo.StatusViewLayout>

4、loading.xml、error.xml和empty.xml可以自己定义

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:gravity="center_horizontal"              android:orientation="vertical">    <ProgressBar        android:id="@+id/progressBar"        android:layout_width="30dp"        android:layout_height="30dp"/>    <TextView        android:id="@+id/loading"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:text="数据加载中..."        android:textColor="@android:color/darker_gray"        android:textSize="16sp"/>LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:gravity="center_horizontal"    android:orientation="vertical">    <ImageView        android:layout_width="50dp"        android:layout_height="50dp"        android:src="@drawable/icon_status_error" />    <TextView        android:id="@+id/status_view_tv_error"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:text="加载出错了"        android:textColor="@android:color/darker_gray"        android:textSize="16sp" />LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:gravity="center_horizontal"              android:orientation="vertical">    <ImageView        android:layout_width="50dp"        android:layout_height="50dp"        android:src="@drawable/icon_status_empty"/>    <TextView        android:id="@+id/status_tv_empty_msg"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="5dp"        android:text="数据为空"        android:textColor="@android:color/darker_gray"        android:textSize="16sp"/>LinearLayout>

更多相关文章

  1. Android高手进阶教程(十)-----Android(安卓)PopupWindow的使用!!
  2. [置顶] Android之 AndroidManifest.xml 文件解析
  3. android 自动弹出软件盘和不弹出设置
  4. Android(安卓)WIFI框架分析(1)
  5. [Android]高性能MMKV数据交互分析-MMKV初始化
  6. Android:如何给ScrollView添加滑块滚动条
  7. mtopsdk(淘宝系android app使用的sdk)强迫请求通过代理进行抓包
  8. 【Android(安卓)Developers Training】 16. 暂停和恢复一个Activ
  9. Android--Task(stack)的使用

随机推荐

  1. android:autoLink
  2. Android(安卓)Wifi AP软件对比
  3. android ListView的分段显示、分页显示(附
  4. 工作笔记-code
  5. Android 之 添加按钮添加声音
  6. android 源代码 获得 Open Soure Project
  7. 从J2EE转向Android的第三天-----Gallery,
  8. Android RIL源码分析(3)
  9. android 定时器 timer简单例子
  10. 【Android】HTTP请求远端String和byte[]