一、 修改昵称
修改昵称界面很简单, 提供一个单行输入框, 一个完成按钮即可, 简单反而不好设计, 一直弄不出一个满意的界面, 直到我看到了Tim的…
于是…
这个界面真舒服, 其他界面也用这种风格吧…
当时为了找Android默认的背景色费了好大劲, 先是在 ?attr/ 里面找windowBackground怎么都找不到, 后来又用取色器却总是有点差距, 最后才发现这个颜色在 ?android:windowBackground 里面
这个活动的逻辑很简单, 点击完成按钮时获取输入框内容并判断有效性, 然后发送到服务器更新用户昵称, 更新成功后再更新本地SharedPreference里面的内容, 否则提示错误信息, 然后返回上一个活动
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
return true;
case R.id.finish:
final String nameInput = input.getText().toString();
if (nameInput.equals("")){
Toast.makeText(SetUserNameActivity.this, "用户名不能为空", Toast.LENGTH_SHORT).show();
}
else {
Request request = new Request.Builder().url("http://www.baidu.com").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(SetUserNameActivity.this, "网络异常", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onResponse(Response response) throws IOException {
SharedPreferences.Editor editor = spf.edit();
editor.putString("name", nameInput);
editor.apply();
finish();
}
});
}
}
return true;
}
二、 修改密码
修改密码的界面布局很简单, 提供三个输入框分别输入原密码, 新密码, 确认密码, 就像这样
更新密码的过程和更新昵称时一样的, 判断有效性之后统一发送到服务器即可, 这里主要处理的问题是修改成功之后需要清除登录状态并返回到登录界面, 这需要使用一个Collector类来管理所有活动
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<>();
public static void addActivity(Activity activity){
activities.add(activity);
}
public static void removeActivity(Activity activity){
activities.remove(activity);
}
public static void finishAll(){
for (Activity activity: activities){
if (!activity.isFinishing()){
activity.finish();
}
}
}
}
然后定义一个BaseActivity作为所有活动的父类, 在其中实现所有继承它的子类都加入到Collector列表里, 由于它继承了AppCompatActivity, 所以这样的继承是不会有任何问题的
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
这样密码验证通过后只需要清除本地SharedPreference内容然后清空活动列表最后启动登录活动即可, 由于目前模块还没有合并, 就先启动主界面吧
SharedPreferences.Editor editor = spf.edit();
editor.clear();
editor.apply();
ActivityCollector.finishAll();
Intent intent = new Intent(SetUserPasswordActivity.this, MainActivity.class);
startActivity(intent);
三、 修改手机号/邮箱
这两个界面除了显示内容和请求服务器地址不同外都一模一样, 是可以合并为一个活动的, 但是在开发时分开写了, 以后有时间再合并吧, 以修改手机号为例, 创建了两个活动, 第一个用于展示当前绑定状态, 确认后进入第二个活动修改
- 获取验证码之后的倒计时
Android提供了一个计时器类CountDownTimer, 我们需要定义一个内部类继承它然后实现需要的功能
//倒计时
private class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
//计时过程
@Override
public void onTick(long l) {
//防止计时过程中重复点击
btGet.setClickable(false);
btGet.setBackgroundColor(Color.parseColor("#bfbfbf"));
btGet.setText(l/1000+"秒");
}
//计时完毕的方法
@Override
public void onFinish() {
//重新给Button设置文字
btGet.setText("重新获取");
//设置可点击
btGet.setClickable(true);
}
}
- 发送验证码
这一部分应该是要放在服务器端的, 不过现在需要测试数据, 就先用mob平台发送短信吧, 这个时候负责登录注册的小老弟已经注册好mob了, 直接拿他的身份用
首先在项目的build.gradle里面添加
...
repositories {
...
maven {
url "http://mvn.mob.com/android"
}
}
dependencies {
...
classpath 'com.mob.sdk:MobSDK:+'
}
...
然后在app的build.gradle里面添加
apply plugin: "com.mob.sdk"
MobSDK{
appkey "自己的key"
appSecret "自己的Secret"
SMSSDK{
gui false //不用SMSSDK中自带的UI
}
}
发送验证码的代码还是很简单的,
//new倒计时对象,总共的时间,每隔多少秒更新一次时间
final BindPhoneActivity.MyCountDownTimer myCountDownTimer = new BindPhoneActivity.MyCountDownTimer(60000,1000);
//获取验证码按钮点击
btGet.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
phoneInput = phone.getText().toString();
if (phone.length() != 11) Toast.makeText(BindPhoneActivity.this, "手机号码格式不正确", Toast.LENGTH_SHORT).show();
else {
SMSSDK.getVerificationCode("+86", phoneInput); // 发送验证码
/**
* 初始化接收器, 接收验证结果
*/
eventHandler = new EventHandler() {
public void afterEvent(int event, int result, Object data) {
// afterEvent会在子线程被调用,因此如果后续有UI相关操作,需要将数据发送到UI线程
Message msg = new Message();
msg.arg1 = event;
msg.arg2 = result;
msg.obj = data;
new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
int event = msg.arg1;
int result = msg.arg2;
Object data = msg.obj;
if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) {
if (result == SMSSDK.RESULT_COMPLETE) {
// TODO 处理成功得到验证码的结果
} else {
// TODO 处理错误的结果
Toast.makeText(BindPhoneActivity.this, "服务器异常", Toast.LENGTH_SHORT).show();
}
} else if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
if (result == SMSSDK.RESULT_COMPLETE) {
// TODO 处理验证码验证通过的结果
SharedPreferences.Editor editor = spf.edit();
editor.putString("phone", phoneInput);
editor.apply();
finish();
} else {
// TODO 处理错误的结果
Toast.makeText(BindPhoneActivity.this, "验证码错误", Toast.LENGTH_SHORT).show();
}
}
// TODO 其他接口的返回结果也类似,根据event判断当前数据属于哪个接口
return false;
}
}).sendMessage(msg);
}
};
SMSSDK.registerEventHandler(eventHandler);
btFinish.setVisibility(View.VISIBLE);
myCountDownTimer.start();
}
}
});
// 确认按钮点击时发送到mob进行校验
btFinish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String codeInput = code.getText().toString();
if (!codeInput.equals("")) {
SMSSDK.submitVerificationCode("+86", phoneInput, code.getText().toString());
}
}
});