Android 请求网络loading 结果显示error empty界面

在进行网络请求中,我们希望给用户一个提示,让用户知道正在加载中(就是一个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"?>
<!-- loading.xml -->
<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"?>
<!-- error.xml -->
<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"?>
<!-- empty.xml -->
<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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值