Android要求ネットワークloading結果表示error emptyインタフェース

21165 ワード

ネットワークリクエストでは、ロード中(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レイアウトと見なすことができます.

<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は自分で定義できます


<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>


<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>


<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>