最近在做项目的时候,项目涉及到了与服务器的交互,那么自然而然的在与服务器交互的过程中,会出现网络连接失败的情况,那么我们这时候就应该在界面上显示“网络故障”之类的提示语来提醒用户,一个activity的实现这种功能还好,就是在xml里放一个布局,平常时候设置属性android:visibility=”gone”,而一旦捕获到网络异常的情况,设置这个布局的属性为android:visibility=”visible”,可是一旦activity数量一多,那这个布局也就要重复的findViewById,频繁的设置View visibility属性,很明显,代码冗余了,那么怎么解决这个问题呢?这里就要用到安卓中基类的设计了。笔者写了一个小DEMO实现了一下,运行效果图如下:
看了这个动态图,不少人大呼:你这是什么?点两个按钮?点了两个textview?弹出了两下toast?就完了?事实上两个按钮是为了模拟网络环境的变化,而textview的显示与后退的箭头退出应用程序都用到了基类,如果我们一个项目有几十个activity,那么我们要把回退箭头findViewById几十遍?然后设置几十遍点击事件吗?很明显写重复的代码不是我们所想要的,好了,现在开工吧。
新建一个BaseActivity继承与Activity,在这个基类中写好一些代码,然后让其它的activity继承于BaseActivity就可以了,BaseActivity的xml文件如下:
base_activity.xml
<RelativeLayout 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_bar_layout"
/>
<include
layout="@layout/exception_layout"
/>
RelativeLayout>
其中包含了两个layout,其中的title_bar_layout.xml代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="46dip"
android:orientation="vertical"
android:background="#0374D9" >
<ImageView
android:id="@+id/iv_back"
android:layout_width="50dip"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:src="@drawable/back_arrow_left" />
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="18sp"
android:textColor="#ffffff"
android:text="页面标题" />
RelativeLayout>
exception_layout.xml代码如下:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/tv_no_net"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="20sp"
android:textColor="#000"
android:visibility="gone"
android:text="暂无网络" />
<TextView
android:id="@+id/tv_no_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="20sp"
android:textColor="#000"
android:visibility="gone"
android:text="暂无数据" />
RelativeLayout>
exception_layout里面放了两个textview,就是页面无数据时候显示的内容,还有是网络连接失败时显示的内容。
好了,现在来看看BaseActivity代码:
public abstract class BaseActivity extends Activity {
//没有网络的提示信息
TextView tv_no_net;
//服务器返回的json数据为空,那么应该显示没有数据的页面
TextView tv_no_info;
//标题栏的返回按钮
ImageView iv_back;
//标题栏的标题文字
TextView tv_title;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_activity);
initContentView(savedInstanceState);
init();
}
private void init() {
tv_no_net=(TextView) findViewById(R.id.tv_no_net);
tv_no_info=(TextView) findViewById(R.id.tv_no_info);
iv_back=(ImageView) findViewById(R.id.iv_back);
tv_title=(TextView) findViewById(R.id.tv_title);
tv_no_net.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
OnNoNetClick(v);;
}
});
tv_no_info.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
OnNoInfoClick(v);
}
});
iv_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
OnBackClick(v);
}
});
tv_title.setText(SetTitleString());
}
//一些抽象方法,继承了BaseActivity的类必须实现这些方法
protected abstract String SetTitleString();
protected abstract void OnBackClick(View v);
protected abstract void OnNoNetClick(View v);
protected abstract void OnNoInfoClick(View v);
protected abstract void initContentView(Bundle savedInstanceState);
protected void setNoNet(){
tv_no_net.setVisibility(View.VISIBLE);
tv_no_info.setVisibility(View.GONE);
}
protected void setNoInfo(){
tv_no_net.setVisibility(View.GONE);
tv_no_info.setVisibility(View.VISIBLE);
}
}
BaseActivity类添加了abstract关键字,那么说明该类是抽象类,
一个抽象类里面可以有抽象方法,也可以没有抽象方法;
可以有普通方法,也可以没有普通方法;
但是,如果一个类里面有abstract修饰的方法,那么该类肯定是抽象类。
一个类继承了一个抽象父类,那么必须要实现父类中所有的抽象方法;
建议对abstract概念模糊的同学了解一下基础,再来看这篇文章。
好了,那么,我们的MainActivity就继承BaseActivity了~~~自然而然要实现父类的抽象方法,具体看MainActivity代码:
public class MainActivity extends BaseActivity {
@Override
protected void initContentView(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
Button bt_no_info=(Button) findViewById(R.id.bt_no_info);
Button bt_no_net=(Button) findViewById(R.id.bt_no_net);
//这两个按钮是模拟两种情况,
bt_no_info.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//当网络故障时,调用该方法
setNoNet();
}
});
bt_no_net.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//当这个页面没有数据显示时,调用该方法
setNoInfo();
}
});
}
@Override
protected void OnNoNetClick(View v) {
Toast.makeText(getApplicationContext(), "no net click", 0).show();
}
@Override
protected void OnNoInfoClick(View v) {
Toast.makeText(getApplicationContext(), "no info click", 0).show();
}
@Override
protected String SetTitleString() {
return "这是第一个页面";
}
@Override
protected void OnBackClick(View v) {
finish();
}
}
MainActivity中的两个button点击事件是为了模拟网络环境的变化,
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rl_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
android:id="@+id/title_bar"
layout="@layout/title_bar_layout" />
<include layout="@layout/exception_layout" />
<Button
android:id="@+id/bt_no_net"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/title_bar"
android:text="显示无网络情况" />
<Button
android:id="@+id/bt_no_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title_bar"
android:layout_toRightOf="@+id/bt_no_net"
android:text="显示无数据情况" />
RelativeLayout>
好了,就说这么多了,具体还是要自己体会abstract这个关键点~~