您的位置:首页 > 移动开发 > Android开发

【Android实战】----从Activity入手(编写BaseActivity)

2017-02-07 15:55 274 查看
关于Android实战篇系列,一直不知从何入手写。基本概念介绍对于实战篇系列来讲没有太大意义,本系列一如Spring实战篇系列所倡导的理念一样:知其然知其所以然,难点、疑点一网打尽(有点狂妄了)。还是决定从头开始,这里对基本概念不做过多介绍,主要介绍使用。

一、背景知识

说到Activity,做Android的一点都不会陌生,真正项目开发中不止会用到Activity,而且会抽象出BaseActivity,其中处理公共部分(比如标题、回调函数等),具体部分还是有具体的Activity处理,这里也是利用了java中的设计模式——策略模式

二、BaseActivity配置

/**
* 基本Activity,供其他Activity继承,实现了回调及title设置、返回按键等
*/
public class BaseActivity extends Activity  implements TextWatcher,RetrofitCallBack {
protected ProgressDialog waitDialog;
/**
* 标记标题左右两边的类型:文字
*/
protected final int TITLE_TYPE_TEXT = 0;
/**
* 标记标题左右两边的类型:图片
*/
protected final int TITLE_TYPE_IMG = 1;
public MyApplication application;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
application = (MyApplication) getApplicationContext();

}

@Override
protected void onDestroy() {
super.onDestroy();
dismissWaitDialog();
}

@Override
protected void onPause() {
super.onPause();
}

@Override
protected void onResume() {
super.onResume();
// 判断界面再次转到前台的时候,主题是否发生改变.如果改变了,则需要重新加载activity
// this.recreate();

}

@Override
protected void onStop() {
super.onStop();
}

/**
* 需在setContentView方法之后调用. 设置后,如果不对左侧的事件进行监听,默认的点击事件是结束当前界面.
* <p>
* 标题传资源id和字符串皆可.
* <p>
* 如果某一侧显示的是图片,则那一侧只能传对应的图片资源id.如果是文字,则资源id和字符串皆可.
*
* @param title
*            标题
* @param left
*            是否显示左侧的部分
* @param leftType
*            左侧的类型
* @param l
*            左侧部分内容
* @param right
*            是否显示右侧的部分
* @param rightType
*            右侧的类型
* @param r
*            右侧部分的内容
*/
protected void setTitle(Object title, boolean left, int leftType, Object l,
boolean right, int rightType, Object r) {
try {
TextView tvTitle = (TextView) findViewById(R.id.tv_title);
TextView tvLeft = (TextView) findViewById(R.id.tv_title_left);
LinearLayout llLeft = (LinearLayout) findViewById(R.id.ll_title_left);
ImageView ivLeft = (ImageView) findViewById(R.id.iv_title_left);
TextView tvRight = (TextView) findViewById(R.id.tv_title_right);
ImageView ivRight = (ImageView) findViewById(R.id.iv_title_right);
LinearLayout llRight = (LinearLayout) findViewById(R.id.ll_title_right);
if (title != null && title instanceof String) {
if (!TextUtils.isEmpty((String) title)) {
tvTitle.setVisibility(View.VISIBLE);
tvTitle.setText((String) title);
} else {
tvTitle.setVisibility(View.INVISIBLE);
}
} else if (title != null && title instanceof Integer) {
if (((Integer) title) > 0) {
tvTitle.setVisibility(View.VISIBLE);
tvTitle.setText((Integer) title);
} else {
tvTitle.setVisibility(View.INVISIBLE);
}

}
if (left) {
llLeft.setVisibility(View.VISIBLE);
if (leftType == TITLE_TYPE_TEXT) {
ivLeft.setVisibility(View.GONE);
tvLeft.setVisibility(View.VISIBLE);
if (l instanceof String) {
tvLeft.setText((String) l);
} else if (l instanceof Integer) {
tvLeft.setText((Integer) l);
}
} else if (leftType == TITLE_TYPE_IMG) {
ivLeft.setVisibility(View.VISIBLE);
tvLeft.setVisibility(View.GONE);
if (l instanceof Integer) {
ivLeft.setImageResource((Integer) l);
}

}
} else {
llLeft.setVisibility(View.INVISIBLE);
}
if (right) {
llRight.setVisibility(View.VISIBLE);
if (rightType == TITLE_TYPE_TEXT) {
ivRight.setVisibility(View.GONE);
tvRight.setVisibility(View.VISIBLE);
if (r instanceof String) {
tvRight.setText((String) r);
} else if (r instanceof Integer) {
tvRight.setText((Integer) r);
}
} else if (rightType == TITLE_TYPE_IMG) {
ivRight.setVisibility(View.VISIBLE);
tvRight.setVisibility(View.GONE);
if (r instanceof Integer) {
ivRight.setImageResource((Integer) r);
}
}
} else {
llRight.setVisibility(View.INVISIBLE);
}

} catch (Exception e) {

}
}

/**
* 设置点击左上角的返回事件.默认是finish界面
*/
protected void registerBack() {
LinearLayout llLeft = (LinearLayout) findViewById(R.id.ll_title_left);
llLeft.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
BaseActivity.this.finish();
}
});
}

/**
* 设置点击右上角的返回事件.
*/
protected void rightDo() {
LinearLayout llRight = (LinearLayout) findViewById(R.id.ll_title_right);
llRight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
rightDoWhat();
}
});
}

protected void rightDoWhat() {

}

// 封装跳转
public void openActivity(Class<?> c) {
openActivity(c, null);
}

// 跳转 传递数据 bundel
public void openActivity(Class<?> c, Bundle b) {
openActivity(c, b, null);
}

public void openActivity(Class<?> c, Bundle b, Uri uri) {
Intent intent = new Intent(this, c);
if (b != null) {
intent.putExtras(b);
}
if (uri != null) {
intent.setData(uri);
}

startActivity(intent);
}

/**
* 跳转登录界面
*/
protected void goLogin() {
Intent intent = new Intent(this, LoginActivity.class);
intent.putExtra(Constant.NEEDLOGIN, true);
startActivityForResult(intent, 33);
}

/**
* 全局等待对话框
*/
public void showWaitDialog() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (waitDialog == null || !waitDialog.isShowing()) {
waitDialog = new ProgressDialog(BaseActivity.this);
waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
waitDialog.setCanceledOnTouchOutside(false);
ImageView view = new ImageView(BaseActivity.this);
view.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
Animation loadAnimation = AnimationUtils.loadAnimation(
BaseActivity.this, R.anim.rotate);
view.startAnimation(loadAnimation);
loadAnimation.start();
view.setImageResource(R.drawable.loading);
// waitDialog.setCancelable(false);
waitDialog.show();
waitDialog.setContentView(view);
LogUtil.i("waitDialong.......");
}

}
});

}

public void dismissWaitDialog() {
this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (waitDialog != null && waitDialog.isShowing()) {
waitDialog.dismiss();
waitDialog = null;
}
}
});

}

/**
* textWatcher的实现类,用于监听Editable的变化
* @param s
* @param start
* @param count
* @param after
*/
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {

}

@Override
public void afterTextChanged(Editable s) {

}

/**
* retrofitcallback方法实现,将response返回给Activity
* @param response  返回数据
* @param method    回调方法标志
*/
@Override
public void onResponse(Response response, int method) {
dismissWaitDialog();
}

@Override
public void onFailure(Response response, int method) {
dismissWaitDialog();
}
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}

}

其中BaseActivity继承了Activity(这个是必须滴,凡是Activity都要集成SDK中的Activity),实现了TextWatcher(监听Editable变化,后面会介绍),实现了RetrofitCallBack(retrofit的回调接口,这个在后面说道retrofit的时候会说明);除此之外,还设置了共用的title,返回键,openActivity,goLogin,等待对话框等。

三、BaseActivity的使用

下面以登录界面为例,介绍BaseActivity的使用

1)先看界面

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey_light" >

<include
android:id="@+id/title"
android:layout_alignParentTop="true"
layout="@layout/layout_stub_title" />

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/distanse60">

<EditText
android:id="@+id/et_account"
android:layout_width="match_parent"
android:layout_height="@dimen/distanse50"
android:background="@drawable/reg_input_bg2"
android:drawableLeft="@drawable/phone"
android:drawablePadding="@dimen/distanse10"
android:hint="请输入手机/用户名"
android:paddingLeft="@dimen/distanse15"
android:paddingRight="@dimen/distanse10"
android:textColor="@color/lightblack" />
<View android:layout_width="match_parent" android:layout_height="1dp"
android:background="#ccc" />
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="@dimen/distanse50"
android:background="@drawable/reg_input_bg2"
android:drawableLeft="@drawable/password"
android:drawablePadding="@dimen/distanse10"
android:hint="登录密码"
android:inputType="textPassword"
android:paddingLeft="@dimen/distanse15"
android:paddingRight="@dimen/distanse10"
android:textColor="@color/lightblack" />

<TextView
android:id="@+id/tv_sure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/distanse10"
android:layout_marginRight="@dimen/distanse10"
android:layout_marginTop="@dimen/distanse50"
android:padding="@dimen/distanse10"
android:background="@drawable/buttonstyle"
android:enabled="false"
android:gravity="center"
android:text="确定"
android:textColor="@color/white"
android:textSize="@dimen/text_size16" />

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/tv_reset"
android:layout_width="match_parent"
android:layout_height="@dimen/distanse40"
android:layout_marginLeft="@dimen/distanse15"
android:layout_marginRight="@dimen/distanse15"
android:layout_marginTop="@dimen/distanse10"
android:drawablePadding="@dimen/distanse5"
android:gravity="right"
android:text="忘记密码"
android:textColor="@color/light_blue"
android:textSize="@dimen/text_size15"
android:layout_weight="1" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="@dimen/distanse10">

<TextView
android:id="@+id/tv_reg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="@dimen/distanse10"
android:text="还没有账号?现在注册"
android:textColor="@color/light_blue"
android:textSize="@dimen/text_size14"
android:layout_weight="1" />
</LinearLayout>

</LinearLayout>

</RelativeLayout>

 


其中引入了共用title布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_title"
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="@color/blue1"
android:gravity="center_vertical" >

<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/ll_title_right"
android:layout_toRightOf="@+id/ll_title_left"
android:ellipsize="end"
android:gravity="center"
android:text="New Text"
android:textColor="@color/white"
android:textSize="20sp" />

<LinearLayout
android:id="@+id/ll_title_left"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="center_vertical|left"
android:minWidth="80dp"
android:orientation="horizontal" >

<ImageView
android:id="@+id/iv_title_left"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@drawable/to_left" />

<TextView
android:id="@+id/tv_title_left"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical|left"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="New Text"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="gone" />
</LinearLayout>

<LinearLayout
android:id="@+id/ll_title_right"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:gravity="center_vertical|right"
android:minWidth="80dp"
android:orientation="horizontal" >

<ImageView
android:id="@+id/iv_title_right"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@drawable/to_left" />

<TextView
android:id="@+id/tv_title_right"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center_vertical|right"
android:paddingRight="10dp"
android:text="New Text"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="gone" />
</LinearLayout>

</RelativeLayout>


2)LoginActivity

public class LoginActivity extends BaseActivity {
@BindView(R.id.et_account)
EditText etAccount;
@BindView(R.id.et_pwd)
EditText etPwd;
@BindView(R.id.tv_reg)
TextView tvReg;
@BindView(R.id.tv_sure)
TextView tvSure;
private String account, pwd, userId, password;
private boolean needLogin;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_login);    //set布局
ButterKnife.bind(this);
setTitle(R.string.login, true, TITLE_TYPE_IMG, R.drawable.to_left,
true, TITLE_TYPE_TEXT, "");       //基类方法,设置title
initView();
initData();
}

private void initView() {
registerBack();
//设置text变化监听器
etAccount.addTextChangedListener(this);
etPwd.addTextChangedListener(this);
tvReg.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);// 下划线
}

/**
* 根据是否输入值,判断是否显示确定按钮
* @param s
*/
@Override
public void afterTextChanged(Editable s) {
super.afterTextChanged(s);
String userStr = etAccount.getText().toString();
String pwdStr = etPwd.getText().toString();
if(userStr.length() * pwdStr.length() != 0){
tvSure.setEnabled(true);
}else{
tvSure.setEnabled(false);
}
}

private void initData() {
account = application.getUserinfobean().getPhoneNumber();
if (!StringUtil.isEmpty(account)) {
etAccount.setText(account);
}

Intent intent = getIntent();
if (intent.hasExtra(Constant.NEEDLOGIN)) {
needLogin = intent.getBooleanExtra(Constant.NEEDLOGIN, false);
}
}

@OnClick({R.id.tv_sure, R.id.tv_reset, R.id.tv_reg})
public void onClick(View view) {
account = etAccount.getText() + "";
switch (view.getId()) {
case R.id.tv_sure:
pwd = etPwd.getText() + "";
if (StringUtil.isEmpty(account)) {
ToastUtil.makeShortText(this, "请输入登录账号");
return;
}
if (StringUtil.isEmpty(pwd)) {
ToastUtil.makeShortText(this, "请输入登录密码");
return;
}
if (pwd.length() < 6 || pwd.length() > 16) {
ToastUtil.makeShortText(this, "密码不能小于6位或大于16位");
return;
}
getUserById(account);

break;
case R.id.tv_reg:
openActivity(RegisterActivity.class);
break;
case R.id.tv_reset:
openActivity(ResetPwdActivity.class);
break;
default:
break;
}
}

private void getLogin(String userId, String password, String loginType) {
showWaitDialog();
Map<String, Object> signMap = new HashMap<String, Object>();
signMap.put("name", userId);
signMap.put("pwd", password);
signMap.put("loginType", loginType);
Map<String, String> reqMap = SignUtil.jsonMd5(signMap);
RetrofitHttpRequest.addToEnqueue(RetrofitHttpRequest.getInstance().mHttpService.login(reqMap),
this, HttpStaticApi.HTTP_LOGIN);
}

/**
* 根据用户名获取userId,加密用md5(userId+pwd)
*/
private void getUserById(String name) {
showWaitDialog();
Map<String, Object> signMap = new HashMap<String, Object>();
signMap.put("name", name);
Map<String, String> reqMap = SignUtil.jsonMd5(signMap);
RetrofitHttpRequest.addToEnqueue(RetrofitHttpRequest.getInstance().mHttpService.getUserById(reqMap),
this, HttpStaticApi.HTTP_GETUSERBYID);
}

@Override
public void onResponse(Response response, int method) {
super.onResponse(response, method);
switch (method) {
case HttpStaticApi.HTTP_GETUSERBYID:
UserIdBean userIdBean = (UserIdBean) response.body();
UserIdBean.ResDataBean resDataBean = userIdBean.getResData();
if (HttpConst.STATUS_SUC.equals(resDataBean.getStatus())) {
userId = resDataBean.getData();
password = StringUtil.md5(userId + pwd);
LogUtil.e(password);
getLogin(account, password, "1");
} else {
ToastUtil.makeShortText(this, resDataBean.getMessage());
}
break;
case HttpStaticApi.HTTP_LOGIN:
UserBean userBean = (UserBean) response.body();
UserBean.ResDataBean resDataBean1 = userBean.getResData();
if (HttpConst.STATUS_SUC.equals(resDataBean1.getStatus())) {
UserBean.ResDataBean.DataBean dataBean = resDataBean1.getData();
Bundle bundle = new Bundle();
bundle.putString("user_id", userId);
bundle.putString("user_name", dataBean.getCustomerName());
bundle.putString("phone", dataBean.getMobile());
bundle.putString("nickName", dataBean.getNickName());
bundle.putString("email", dataBean.getEmail());
bundle.putBoolean("isBinding", dataBean.getIsbinding().equals("1") ? true : false);
application.getUserinfobean().setAccess(bundle);
//从需要登录页跳转的返回目标页,直接点击登录的跳转首页
if (!needLogin){
openActivity(MainActivity.class);
}
finish();
} else {
ToastUtil.makeShortText(this, "登录失败" + resDataBean1.getMessage());
}
break;
default:
break;
}
}

后面retrofit相关是和服务器通信的,这个后面会有专题介绍。还看到控件的获取和点击事件的设置用了Butterknife,@BindView和@OnClick,这个将在下一章进行介绍Butterknife的使用

四、AndroidManifest.xml

当然不要忘了在AndroidManifest.xml进行设置,否则无法启动

<activity
android:name="com.xxx.xxx.login.LoginActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|stateHidden" />


运行效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android BaseActivity