Android实战----从Activity入手(编写BaseActivity)
Posted Herman-Hong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实战----从Activity入手(编写BaseActivity)相关的知识,希望对你有一定的参考价值。
关于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实战----从Activity入手(编写BaseActivity)的主要内容,如果未能解决你的问题,请参考以下文章
Android项目实战(三十七):Activity管理及BaseActivity的实现