一般来说,项目中都会有多个Activity或者Fragment,每个界面都会有一些相同的地方,比如标题栏、无数据界面、网络错误界面,每个界面都写就会显得很重复,也不便于维护。所以这个时候就有必要写一个基类来进行封装,也就是BaseActivity或者BaseFragment
先看一下效果
无数据和网络错误的情况。对于上边的标题栏,可能有多种情况,有标题栏,无标题栏,是否有返回按钮,右边是否显示文字或图片。这些情况我们都可以写在基类中。这些公用的界面都是写在BaseActivity的对应的xml文件中。
activity_base.xml
里面用include添加进两个布局title_bar就是标题栏,state_layout是无数据和无网络的布局。
title_bar.xml
state_layout.xml
两个布局就不多说了,主要看BaseActivity的代码
public class BaseActivity extends AppCompatActivity {
LinearLayout mRootBaseView;//根布局
View titleView;//include的titleBar
TextView tvLeft;//titleBar左边的返回键
TextView tvMiddle;//titleBar的标题
View mStateLayout;//include的state_layout
LinearLayout ll_page_state_error;//stateLayout网络错误的布局
LinearLayout ll_page_state_empty;//stateLayout无数据的布局
Button btReload;//网络错误重新加载的布局
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//注意:这里的setContentView必须有super才可以,需要走父类方法
super.setContentView(R.layout.activity_base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getWindow().getDecorView()
.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
initBaseView();
/*//5.0以下设置状态栏颜色
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
new SystemStatusManager(this).setTranslucentStatus(R.color.colorPrimaryDark);
getWindow().getDecorView()
.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}*/
}
//这里控件初始化没用ButterKnife 会报错 原因暂时没找到
public void initBaseView() {
mRootBaseView = (LinearLayout) findViewById(R.id.activity_base_root);
titleView = findViewById(R.id.activity_base_title_bar);
tvLeft = (TextView) findViewById(R.id.title_bart_tv_left);
tvMiddle = (TextView) findViewById(R.id.title_bart_tv_middle);
mStateLayout = findViewById(R.id.activity_base_state_layout);
btReload = (Button) findViewById(R.id.state_layout_error_bt);
ll_page_state_empty = (LinearLayout) findViewById(R.id.state_layout_empty);
ll_page_state_error = (LinearLayout) findViewById(R.id.state_layout_error);
}
/**
* 必须重写setContentView注意不能够添加这行代码 目的将当前界面的布局添加到BaseActivity中去
* super.setContentView(R.layout.activity_base);
*/
@Override
public void setContentView(int layoutResID) {
View view = getLayoutInflater().inflate(layoutResID, null);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
if (null != mRootBaseView) {
mRootBaseView.addView(view, lp);
}
}
/**
*
* @param titleBarIsShow titleBar是否显示
* @param tvLeftIsShow 返回键是否显示
* @param middleText 中间的文字
*/
public void initTitleBar(boolean titleBarIsShow, boolean tvLeftIsShow,
String middleText) {
if (titleBarIsShow == true) {
if (!tvLeftIsShow) {
tvLeft.setVisibility(View.GONE);
} else {
tvLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
}
tvMiddle.setText(middleText);
} else {
titleView.setVisibility(View.GONE);
}
}
/**
* 切换页面的布局
* @param pageState 页面状态 NORMAL EMPTY ERROR
*/
public void changePageState(PageState pageState) {
switch (pageState) {
case NORMAL:
if (mStateLayout.getVisibility() == View.VISIBLE) {
mStateLayout.setVisibility(View.GONE);
}
break;
case ERROR:
if (mStateLayout.getVisibility() == View.GONE) {
mStateLayout.setVisibility(View.VISIBLE);
ll_page_state_error.setVisibility(View.VISIBLE);
btReload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
reloadInterface.reloadClickListener();
}
});
ll_page_state_empty.setVisibility(View.GONE);
}
break;
case EMPTY:
if (mStateLayout.getVisibility() == View.GONE) {
mStateLayout.setVisibility(View.VISIBLE);
ll_page_state_error.setVisibility(View.GONE);
ll_page_state_empty.setVisibility(View.VISIBLE);
}
break;
}
}
//网络错误重新加载的接口
public ReloadInterface reloadInterface;
public void setReloadInterface(ReloadInterface reloadInterface) {
this.reloadInterface = reloadInterface;
}
public interface ReloadInterface {
void reloadClickListener();
}
public enum PageState {
/**
* 数据内容显示正常
*/
NORMAL,
/**
* 数据为空
*/
EMPTY,
/**
* 数据加载失败
*/
ERROR
}
}
在MyMessageActivity继承BaseActivity并实现ReloadInterface接口,如果该界面没有用到则不用实现此接口
public class MyMessageActivity extends BaseActivity implements ReloadInterface {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_message);//重载BaseActivity的setContentView方法
initTitleBar(true, true, "我的消息");
setReloadInterface(this);
}
@Override
public void reloadClickListener() {
//You want to do
}
}
对于布局的切换,主要是在网络请求里调用,比如OkHttp在请求失败的时候调用changePageState(PageState.Error);
okHttpHelper.post(Constants.HTTP.BaseUrl, params, new ProgressDialogCallBack(context) {
@Override
public void onFailure(Request request, IOException e) {
changePageState(PageState.ERROR);//切换成网络异常布局
}
@Override
public void onSuccess(Response response, MessageEntity messageEntity) {
List messageList = messageEntity.getMsg().getRows();
if (messageList.size() == 0) {//数据为空显示无数据
changePageState(PageState.EMPTY);
}else{//数据不为空正常显示
changePageState(PageState.NORMAL);
}
}
});
如果后期项目需要,还会继续更新BaseActivity。
明天就是端午节了,大家端午节快乐!