第一步:自定义一个ProgressRelativeLayout类,如下
package com.example.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ProgressRelativeLayout extends RelativeLayout {
private static final String TAG_PROGRESS = "ProgressLayout.TAG_PROGRESS";
private static final String TAG_ERROR = "ProgressLayout.TAG_ERROR";
public static enum State {
CONTENT, PROGRESS, ERROR
}
private View mProgressView;
private TextView mErrorTextView;
private List<View> mContentViews = new ArrayList<View>();
private State mState = State.CONTENT;
public ProgressRelativeLayout(Context context) {
super(context);
}
public ProgressRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public ProgressRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
private void init(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressRelativeLayout);
int backgroundColor = a.getColor(R.styleable.ProgressRelativeLayout_progressBackground, Color.TRANSPARENT);
boolean progress = a.getBoolean(R.styleable.ProgressRelativeLayout_progress, false);
a.recycle();
LayoutParams layoutParams;
// if progressBackground color == Color.TRANSPARENT just add progress bar
if (backgroundColor == Color.TRANSPARENT) {
mProgressView = new ProgressBar(getContext());
layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(CENTER_IN_PARENT);
} else { // else wrap progress bar in LinearLayout and set background color to LinearLayout
LinearLayout linearLayout = new LinearLayout(getContext());
linearLayout.setGravity(Gravity.CENTER);
linearLayout.setBackgroundColor(backgroundColor);
layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
ProgressBar progressBar = new ProgressBar(getContext());
linearLayout.addView(progressBar);
mProgressView = linearLayout;
}
mProgressView.setTag(TAG_PROGRESS);
addView(mProgressView, layoutParams);
// add error text view
mErrorTextView = new TextView(getContext());
mErrorTextView.setTag(TAG_ERROR);
layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(CENTER_IN_PARENT);
addView(mErrorTextView, layoutParams);
mProgressView.setVisibility(progress ? VISIBLE : GONE);
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
super.addView(child, index, params);
if (child.getTag() == null || (!child.getTag().equals(TAG_PROGRESS) && !child.getTag().equals(TAG_ERROR))) {
mContentViews.add(child);
}
}
public void showProgress() {
switchState(State.PROGRESS, null, Collections.<Integer>emptyList());
}
public void showProgress(List<Integer> skipIds) {
switchState(State.PROGRESS, null, skipIds);
}
public void showErrorText() {
switchState(State.ERROR, null, Collections.<Integer>emptyList());
}
public void showErrorText(List<Integer> skipIds) {
switchState(State.ERROR, null, skipIds);
}
public void showErrorText(String error) {
switchState(State.ERROR, error, Collections.<Integer>emptyList());
}
public void showErrorText(String error, List<Integer> skipIds) {
switchState(State.ERROR, error, skipIds);
}
public void showContent() {
switchState(State.CONTENT, null, Collections.<Integer>emptyList());
}
public void showContent(List<Integer> skipIds) {
switchState(State.CONTENT, null, skipIds);
}
public void switchState(State state) {
switchState(state, null, Collections.<Integer>emptyList());
}
public void switchState(State state, String errorText) {
switchState(state, errorText, Collections.<Integer>emptyList());
}
public void switchState(State state, List<Integer> skipIds) {
switchState(state, null, skipIds);
}
public void switchState(State state, String errorText, List<Integer> skipIds) {
mState = state;
switch (state) {
case CONTENT:
mErrorTextView.setVisibility(View.GONE);
mProgressView.setVisibility(View.GONE);
setContentVisibility(true, skipIds);
break;
case PROGRESS:
mErrorTextView.setVisibility(View.GONE);
mProgressView.setVisibility(View.VISIBLE);
setContentVisibility(false, skipIds);
break;
case ERROR:
if (TextUtils.isEmpty(errorText)) {
mErrorTextView.setText(R.string.unknown_error);
} else {
mErrorTextView.setText(errorText);
}
mErrorTextView.setVisibility(View.VISIBLE);
mProgressView.setVisibility(View.GONE);
setContentVisibility(false, skipIds);
break;
}
}
public State getState() {
return mState;
}
public boolean isProgress() {
return mState == State.PROGRESS;
}
public boolean isContent() {
return mState == State.CONTENT;
}
public boolean isError() {
return mState == State.ERROR;
}
private void setContentVisibility(boolean visible, List<Integer> skipIds) {
for (View v : mContentViews) {
if (!skipIds.contains(v.getId())) {
v.setVisibility(visible ? View.VISIBLE : View.GONE);
}
}
}
}
第二步:在布局文件中需要网络请求的地方引用
<?xml version="1.0" encoding="utf-8"?>
<com.example.view.ProgressRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progress_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<span style="white-space:pre"> </span>...
</LinearLayout>
</com.example.view.ProgressRelativeLayout>
第三步:在初始化布局时显示进度并开始加载网络数据,根据加载的状态取消进度,并显示相应信息
显示进度
_progressLinearLayout = (ProgressRelativeLayout)findViewById(R.id.progress_layout);
_progressLinearLayout.showProgress();
在加载网络数据失败的回调中,显示错误信息
<span style="white-space:pre"> </span> @Override
public void onFailure(Response resp, Throwable e) {
String msg = getString(R.string.film_collect_get_error);
_progressLinearLayout.showErrorText(msg);//在此方法的最后调用
}
在加载网络数据成功的回调中,显示数据
<span style="white-space:pre"> </span> @Override
public void onSuccess(Response resp) {
//在此方法的最后调用
_progressLinearLayout.showContent();
}