特此感谢:https://github.com/wenzhihao123/Android-rxjava-retrofit-okhttp-app
先上效果图:
根据不同的状态,去更新不同的UI。
正常状态: (数据加载完毕,显示ContentView)
隐藏异常状态View;
异常状态: (加载数据中,数据加载失败)
可以看见非正常状态下,UI布局都是一样的。不一样的只是图片和文字。
原理: 布局当中引入error状态布局,在加载数据时,让errorView显示,数据加载完成之后则将其隐藏掉。
异常状态布局,默认情况下android:visibility=”gone”不占位隐藏
common_error:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/errorView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_error"
android:layout_width="60dp"
android:layout_height="60dp" />
<TextView
android:id="@+id/tv_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp" />
LinearLayout>
主页Fragment布局:复用引入common_error
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
<include layout="@layout/common_error" />
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
LinearLayout>
开始在BaseFragment中进行封装:
public class BaseFragment extends Fragment {
public LayoutInflater inflater;
public ViewGroup container;
private View view ,errorView;
private ImageView error_iv;
private TextView error_tv;
private OnReLoadDataListener onReLoadDataListener; //加载数据接口
private RotateAnimation animator; //加载数据时动画旋转图片
public Activity mActivity;
public void setContentView(int layout){
view = inflater.inflate(layout,container,false);
}
public View getContentView(){
return this.view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mActivity = activity;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
this.inflater = inflater;
this.container = container;
return super.onCreateView(inflater, container, savedInstanceState);
}
//初始化errorView
private void initBaseView(){
errorView = findViewById(R.id.errorView);
if(errorView != null){
errorView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onReLoadDataListener!=null){
onReLoadDataListener.request();
}
}
});
}
error_iv = (ImageView)findViewById(R.id.iv_error);
error_tv = (TextView)findViewById(R.id.tv_error);
}
//显示加载页
public void showLoadDataPage(String txt, int resId){
initBaseView();
if(errorView == null){
return;
}
if(error_tv == null){
return;
}
if(error_iv == null){
return;
}
errorView.setVisibility(View.VISIBLE);
error_tv.setText(txt);
error_iv.setImageResource(resId);
if(animator == null){
animator = new RotateAnimation(0f,365f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animator.setDuration(1000);
animator.setRepeatCount(Integer.MAX_VALUE);
animator.startNow();
}
error_iv.setAnimation(animator);
}
//显示异常页
public void showErrorPage(String txt, int resId){
initBaseView();
if(errorView == null){
return;
}
if(error_tv == null){
return;
}
if(error_iv == null){
return;
}
errorView.setVisibility(View.VISIBLE);
error_tv.setText(txt);
error_iv.setImageResource(resId);
error_iv.setAnimation(null);
}
//显示内容页,隐藏异常状态页
public void showContentView(){
initBaseView();
if(errorView == null){
return;
}
if(error_tv == null){
return;
}
if(error_iv == null){
return;
}
errorView.setVisibility(View.GONE);
}
public View findViewById(int id){
return view.findViewById(id);
}
public void setOnReLoadDataListener(OnReLoadDataListener onReLoadDataListener){
this.onReLoadDataListener = onReLoadDataListener;
}
//加载数据接口
public interface OnReLoadDataListener{
void request();
}
}
在子Fragment中的使用:
public class TestFragment extends BaseFragment implements BaseFragment.OnReLoadDataListener {
private RecyclerView mTestRecyclerView;
private LinearLayoutManager mLayoutManager;
private String[] mTestData = new String[10];
private Handler handler = new Handler();
private boolean isLoad = false;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
setContentView(R.layout.fragment_test);
initView();
initData();
return getContentView();
}
private void initView() {
mLayoutManager = new LinearLayoutManager(mActivity);
mTestRecyclerView = (RecyclerView) findViewById(R.id.rv_test);
mTestRecyclerView.setLayoutManager(mLayoutManager);
mTestRecyclerView.setAdapter(new TestAdapter());
setOnReLoadDataListener(this);
}
private void initData() {
int length = mTestData.length;
for (int i = 0; i < length; i++) {
mTestData[i] = "TEST" + i;
}
request();
handler.postDelayed(new Runnable() {
@Override
public void run() {
showErrorPage("请检查网络...",R.drawable.ic_error);
isLoad = true;
}
},3000);
}
@Override
public void request() {
showLoadDataPage("正在加载...", R.drawable.ic_loading);
if(isLoad){
handler.postDelayed(new Runnable() {
@Override
public void run() {
mTestRecyclerView.setAdapter(new TestAdapter());
showContentView();
}
},2000);
}
}
//RecyclerView适配器
class TestAdapter extends RecyclerView.Adapter {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_txt, null);
return new TestHolder(view);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
TestHolder testHolder = (TestHolder) holder;
if(testHolder.item_tv == null){
Log.i("TAG","testHolder.item_tv==null");
}
testHolder.item_tv.setText(mTestData[position]);
}
@Override
public int getItemCount() {
return mTestData.length;
}
class TestHolder extends RecyclerView.ViewHolder {
private TextView item_tv;
public TestHolder(View itemView) {
super(itemView);
item_tv = (TextView)itemView.findViewById(R.id.tv_test);
}
}
}
}
大家有什么不懂的,可以将Demo下载下来慢慢研究(感觉不错,可以star一下):
https://github.com/yangjiechina/FragmentStates
git错误解决:
http://www.cnblogs.com/fangwang/p/5703830.html