在android开发涉及到网络请求数据时,如果请求错误,一般需要添加错误提示,这个错误提示可以做成一个通用的类。
先来看一张没有添加错误提示的图:
再来看一张添加错误提示的图:
先看看主界面的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" >
<include layout="@layout/title_layout" />
<Button android:id="@+id/btn_addErrorBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="addErrorBar" />
<Button android:id="@+id/btn_removeErrorBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="removeErrorBar" />
<FrameLayout android:id="@+id/fl_root" android:layout_width="match_parent" android:layout_height="match_parent" >
<ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="#00000000" />
<TextView android:layout_width="match_parent" android:layout_height="40dp" android:layout_gravity="bottom" android:text="bottom" android:textColor="#ffffff" android:gravity="center" android:background="#88ff0000" />
</FrameLayout>
</LinearLayout>
这个布局中,错误提示的布局将覆盖在在FrameLayout的ListView这个位置,但是不会覆盖FrameLayout的TextView。
再看看主界面Activity:
package com.androidtest.error;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.androidtest.R;
import com.androidtest.base.BaseActivity;
import com.androidtest.utils.ErrorBarHelper;
public class ErrorActivity extends BaseActivity implements OnClickListener{
private TextView title;
private FrameLayout rootView;
private ListView mListView;
private Button btn_addErrorBar,btn_removeErrorBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_error);
init();
}
private void init() {
title=(TextView) findViewById(R.id.title);
title.setText("test error");
findViewById(R.id.back).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
btn_addErrorBar=(Button) findViewById(R.id.btn_addErrorBar);
btn_removeErrorBar=(Button) findViewById(R.id.btn_removeErrorBar);
btn_addErrorBar.setOnClickListener(this);
btn_removeErrorBar.setOnClickListener(this);
rootView=(FrameLayout) findViewById(R.id.fl_root);
mListView=(ListView) findViewById(R.id.listview);
mListView.setAdapter(createAdapter());
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v==btn_addErrorBar) {
ErrorBarHelper.addErrorBar(rootView, mListView, "network error");
} else if(v==btn_removeErrorBar) {
ErrorBarHelper.removeErrorBar(rootView);
}
}
}
主要看onClick事件。
主要的功能在ErrorBarHelper.java类中:
package com.androidtest.utils;
import com.androidtest.R;
import com.androidtest.base.BaseApplication;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class ErrorBarHelper {
private final static int KEY_INDEX=5<<24;
private final static int KEY_VIEW=6<<24;
private static boolean isAdd=false;
public static View creatErrorBar() {
View LoadingErroBar = (View) LayoutInflater.from(BaseApplication.getInstance().getApplicationContext())
.inflate(R.layout.error_layout, null);
return LoadingErroBar;
}
public static void addErrorBar(ViewGroup container,View content, String error) {
addErrorBar(container,content, error, -1, null, "");
}
public static void addErrorBar(ViewGroup container,View content, String error, final Runnable refreshRunnable) {
addErrorBar(container,content, error, -1, refreshRunnable, "");
}
public static void addErrorBar(ViewGroup container,View content, String error, final Runnable refreshRunnable, String buttonName) {
addErrorBar(container,content, error, -1, refreshRunnable, buttonName);
}
public static void initErrorBar(View errorView, String error, int resId, final Runnable refreshRunnable,
String buttonName) {
if (resId >= 0) {
ImageView imageView = (ImageView) errorView.findViewById(R.id.iv_error);
imageView.setImageResource(resId);
}
TextView title = (TextView) errorView.findViewById(R.id.tv_error);
if(TextUtils.isEmpty(error)){
title.setVisibility(View.GONE);
}else{
title.setVisibility(View.VISIBLE);
title.setText(error);
}
Button button = null;
button = (Button) errorView.findViewById(R.id.bt_refresh);
if (button != null && !TextUtils.isEmpty(buttonName)) {
button.setText(buttonName);
}
if (refreshRunnable != null) {
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
refreshRunnable.run();
}
});
} else {
button.setVisibility(View.GONE);
}
}
public static void addErrorBar(final ViewGroup container,final View content, final String error, final int resId,
final Runnable refreshRunnable, final String buttonName) {
Runnable runnable = new Runnable() {
@Override
public void run() {
addErrorBarInUiThread(container,content,
error, resId, refreshRunnable, buttonName);
}
};
BaseApplication.getInstance().
getHandler().post(runnable);
}
public static void addErrorBarInUiThread(ViewGroup container,View content,final String error, final int resId,
final Runnable refreshRunnable, final String buttonName) {
if(container==null || content==null)
return;
removeErrorBar(container);
int index=container.indexOfChild(content);
if(index==-1)
return;
isAdd=true;
container.setTag(KEY_INDEX,index);
container.setTag(KEY_VIEW,content);
View errorView=creatErrorBar();
initErrorBar(errorView, error, resId,
refreshRunnable, buttonName);
container.removeViewAt(index);
container.addView(errorView,index,
content.getLayoutParams());
}
public static void removeErrorBar(ViewGroup container) {
if(isAdd) {
isAdd=false;
int index=(Integer) container.getTag(KEY_INDEX);
View view=(View) container.getTag(KEY_VIEW);
if(view!=null && index!=-1) {
container.removeViewAt(index);
container.addView(
view,index,view.getLayoutParams());
}
}
}
}
关键的点在这两句:container.removeViewAt(index);
container.addView(errorView,index,content.getLayoutParams());
通过这个方法,可以将原有的View和errorView进行动态的替换,同时不影响container中其他的元素。