ClearEdittext 用户登录 注册页面
1.自定义ClearEdittext
/**
* Created by asus on 2016/10/29.
*
* 自定义edittext 删除所有
*/
public class ClearEditText extends EditText implements View.OnFocusChangeListener, TextWatcher {
/**
* 删除按钮的引用
*/
private Drawable mClearDrawable;
public ClearEditText(Context context) {
super(context);
init(context);
}
public ClearEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ClearEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
//获取EditText的DrawableRight,假如没有设置我们就使用默认的图片
mClearDrawable = getCompoundDrawables()[2];
if (mClearDrawable == null) {
//设置按钮
mClearDrawable = getResources().getDrawable(R.drawable.icon_delete_32);
}
//设置图片的固有宽高
mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());
setClearIconVisible(false);//默认图标隐藏
setOnFocusChangeListener(this);//1.焦点改变的监听
addTextChangedListener(this);//2.设入框里面内容发生改变的监听
}
// 1.焦点改变的监听
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus){
setClearIconVisible(getText().length() > 0);//如果里面有值则显示
}else{
setClearIconVisible(false);//否则隐藏
}
}
//2.设入框里面内容发生改变的监听 (复写这个方法)
@Override
public void onTextChanged(CharSequence s, int start, int count, int after) {
if(isFocused()){
setClearIconVisible(s.length() > 0);
//设置只可以输入11位
if(s.length()>11){
setText(s.subSequence(0,11));
setSelection(11);
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
//复写onTouchEvent处理
/**
* 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
* 当我们按下的位置 在 EditText的宽度 - 图标到控件右边的间距 - 图标的宽度 和
* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向就没有考虑
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
if(event.getAction()==MotionEvent.ACTION_UP){//如果是抬起
//如果图片可见
boolean touchable = x > (getWidth() - getTotalPaddingRight())
&& (x < ((getWidth() - getPaddingRight())));
if(touchable){
setText("");
}
}
return super.onTouchEvent(event);
}
//设置图标的显示和隐藏
private void setClearIconVisible(final boolean visible) {
mClearDrawable.setVisible(visible,false);
final Drawable[] compoundDrawables = getCompoundDrawables();
//设置edittext的位置
setCompoundDrawables(
compoundDrawables[0],
compoundDrawables[1],
visible ? mClearDrawable : null,
compoundDrawables[3]);
}
}
2.用户登录
①.保存用户信息
/**
* Created by asus on 2016/10/29.
*
* 保存的用户登录的信息
*/
public class UserLocalData {
//保存到本地sharedpreferenc
public static void putUser(Context context, User user){
String user_json = JSONUtil.toJSON(user);
PreferencesUtils.putString(context, Contants.USER_JSON,user_json);
}
//获取对象
public static User getUser(Context context){
String user_json = PreferencesUtils.getString(context, Contants.USER_JSON);
if(!TextUtils.isEmpty(user_json)){
User user = JSONUtil.fromJson(user_json, User.class);
return user;
}
return null;
}
//清除本地数据
public static void clearUser(Context context){
PreferencesUtils.putString(context, Contants.USER_JSON,"");
}
//保存数据的保存时间
public static void putToken(Context context,String token){
PreferencesUtils.putString(context, Contants.TOKEN,token);
}
//token
public static String getToken(Context context){
String token = PreferencesUtils.getString(context, Contants.TOKEN);
return token;
}
public static void clearToken(Context context){
PreferencesUtils.putString(context, Contants.TOKEN,"");
}
}
②.LoginActivity登录
/**
* Created by asus on 2016/10/29.
*/
public class LoginActivity extends AppCompatActivity {
@ViewInject(R.id.toolbar)
private CnToolbar mToolBar;
@ViewInject(R.id.etxt_phone)
private ClearEditText mEtxtPhone;
@ViewInject(R.id.etxt_pwd)
private ClearEditText mEtxtPwd;
@ViewInject(R.id.btn_login)
private Button btn_login;
@ViewInject(R.id.txt_toReg)//注册账号
private TextView txt_toReg;
private OkHttpHelper okHttpHelper ;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ViewUtils.inject(this);
okHttpHelper = OkHttpHelper.getInstance();
initToolBar();
initView();
}
private void initView() {
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String phone = mEtxtPhone.getText().toString().trim();
String telRegex = "[1][358]\\d{9}";
if(TextUtils.isEmpty(phone)){
ToastUtil.showToast(LoginActivity.this, "请输入手机号码");
return;
}else if(!phone.matches(telRegex)){
ToastUtil.showToast(LoginActivity.this, "请输入正确的手机号码");
return;
}
String pwd = mEtxtPwd.getText().toString().trim();
if(TextUtils.isEmpty(pwd)){
ToastUtil.showToast(LoginActivity.this, "请输入密码");
return;
}
HashMap<String,Object> params = new HashMap<>(2);
params.put("phone",phone);
params.put("password", DESUtil.encode(Contants.DES_KEY,pwd));//加密后的密码,服务器使用这个解密登录
//通过请求数据会返回 1.数据(名字,图片,id,email) 2.token
okHttpHelper.post(Contants.API.LOGIN, params, new SpotsCallBack<LoginRespMsg<User>>(LoginActivity.this,true) {
@Override
public void onSuccess(Response response, LoginRespMsg<User> userLoginRespMsg) {
MyApplication application = MyApplication.getInstance();
application.putUser(userLoginRespMsg.getData(), userLoginRespMsg.getToken());//将数据保存到本地
ToastUtil.showToast(LoginActivity.this,"登录成功");
setResult(RESULT_OK);
finish();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// 隐藏软键盘
imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}
@Override
public void onError(Response response, int code, Exception e) {
}
});
}
});
//注册按钮
txt_toReg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(LoginActivity.this, RegActivity.class);
startActivity(intent);
}
});
}
private void initToolBar() {
mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();//结束页面
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
// 隐藏软键盘
imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0);
}
});
}
}
①.注册页面
public class RegActivity extends Activity {
private static final String TAG = "RegActivity";
// 默认使用中国区号
private static final String DEFAULT_COUNTRY_ID = "42";
@ViewInject(R.id.toolbar)//toolbar
private CnToolbar mToolBar;
@ViewInject(R.id.txtCountry)//国家名字
private TextView mTxtCountry;
@ViewInject(R.id.txtCountryCode)//国家的手机编号+86
private TextView mTxtCountryCode;
@ViewInject(R.id.edittxt_phone)//电话号码
private ClearEditText mEtxtPhone;
@ViewInject(R.id.edittxt_pwd)//密码
private ClearEditText mEtxtPwd;
private SMSEvenHanlder evenHanlder;//自定义gui
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reg);
ViewUtils.inject(this);
initToolBar();
initSMSSDK();
}
//
private void initSMSSDK() {
SMSSDK.initSDK(this, Contants.APPKEY, Contants.APPSRECT);
evenHanlder = new SMSEvenHanlder();
SMSSDK.registerEventHandler(evenHanlder);//注册
String[] country = SMSSDK.getCountry(DEFAULT_COUNTRY_ID);//设置默认的国家和电话号码+86
if (country != null) {
mTxtCountryCode.setText("+"+country[1]);//编号
mTxtCountry.setText(country[0]);//国家名字
}
}
private void initToolBar() {
mToolBar.setRightButtonText("下一步");
mToolBar.setmRightImageButtonOnclickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击时提交电话和国编号到服务器
getCode();
}
});
mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
//自定义handler 回调请求成功
class SMSEvenHanlder extends EventHandler {
@Override
public void afterEvent(final int event, final int result, final Object data) {
super.afterEvent(event, result, data);
runOnUiThread(new Runnable() {
public void run() {
if (result == SMSSDK.RESULT_COMPLETE) {
if (event == SMSSDK.EVENT_GET_SUPPORTED_COUNTRIES) {
// 请求支持国家列表
onCountryListGot((ArrayList<HashMap<String, Object>>) data);
} else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) {
// 请求验证码后,跳转到验证码填写页面
boolean smart = (Boolean) data;
afterVerificationCodeRequested(smart);
}
} else {
if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE
&& data != null
&& (data instanceof UserInterruptException)) {
// 由于此处是开发者自己决定要中断发送的,因此什么都不用做
return;
}
// 根据服务器返回的网络错误,给toast提示
try {
((Throwable) data).printStackTrace();
Throwable throwable = (Throwable) data;
JSONObject object = new JSONObject(
throwable.getMessage());
String des = object.optString("detail");
if (!TextUtils.isEmpty(des)) {
ToastUtil.showToast(RegActivity.this, des);
return;
}
} catch (Exception e) {
SMSLog.getInstance().w(e);
}
}
}
});
}
}
//提交电话号码和国家编号code服务器
private void getCode(){
String phone = mEtxtPhone.getText().toString().trim().replaceAll("\\s*", "");
String code = mTxtCountryCode.getText().toString().trim();
String pwd = mEtxtPwd.getText().toString().trim();
checkPhoneNum(phone,code);
//not 86 +86 请求获取短信验证码
SMSSDK.getVerificationCode(code,phone);
}
//提交时检查电话号码
private void checkPhoneNum(String phone, String code) {
if (code.startsWith("+")) {
code = code.substring(1);
}
if (TextUtils.isEmpty(phone)) {
ToastUtil.showToast(this, "请输入手机号码");
return;
}
if (code == "86") {
if(phone.length() != 11) {
ToastUtil.showToast(this,"手机号码长度不对");
return;
}
}
String rule = "^1(3|5|7|8|4)\\d{9}";
Pattern p = Pattern.compile(rule);
Matcher m = p.matcher(phone);
if (!m.matches()) {
ToastUtil.showToast(this,"您输入的手机号码格式不正确");
return;
}
}
// 解析国家列表
private void onCountryListGot(ArrayList<HashMap<String, Object>> countries) {
for (HashMap<String, Object> country : countries) {
String code = (String) country.get("zone");
String rule = (String) country.get("rule");
if (TextUtils.isEmpty(code) || TextUtils.isEmpty(rule)) {
continue;
}
Log.d(TAG, "code=" + code + "rule=" + rule);
}
}
/** 请求验证码后,跳转到验证码填写页面 */
private void afterVerificationCodeRequested(boolean smart) {
//如果里面包含了空白字符,换行之类的就用空格代替
String phone = mEtxtPhone.getText().toString().trim().replaceAll("\\s*", "");
String code = mTxtCountryCode.getText().toString().trim();
String pwd = mEtxtPwd.getText().toString().trim();
if (code.startsWith("+")) {
code = code.substring(1);
}
Intent intent = new Intent(this,RegSecondActivity.class);
intent.putExtra("phone",phone);
intent.putExtra("pwd",pwd);
intent.putExtra("countryCode",code);
startActivity(intent);
finish();
}
private String[] getCurrentCountry() {
String mcc = getMCC();
String[] country = null;
if (!TextUtils.isEmpty(mcc)) {
country = SMSSDK.getCountryByMCC(mcc);
}
if (country == null) {
Log.w("SMSSDK", "no country found by MCC: " + mcc);
country = SMSSDK.getCountry(DEFAULT_COUNTRY_ID);
}
return country;
}
private String getMCC() {
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
// 返回当前手机注册的网络运营商所在国家的MCC+MNC. 如果没注册到网络就为空.
String networkOperator = tm.getNetworkOperator();
if (!TextUtils.isEmpty(networkOperator)) {
return networkOperator;
}
// 返回SIM卡运营商所在国家的MCC+MNC. 5位或6位. 如果没有SIM卡返回空
return tm.getSimOperator();
}
@Override
protected void onDestroy() {
super.onDestroy();
// SMSSDK.unregisterAllEventHandler();
Log.d("share","已经执行");
SMSSDK.unregisterEventHandler(evenHanlder);
}
}
/* //打开注册页面
RegisterPage registerPage = new RegisterPage();
registerPage.setRegisterCallback(new EventHandler() {
public void afterEvent(int event, int result, Object data) {
// 解析注册结果
if (result == SMSSDK.RESULT_COMPLETE) {
HashMap<String,Object> phoneMap = (HashMap<String, Object>) data;
String country = (String) phoneMap.get("country");
String phone = (String) phoneMap.get("phone");
// 提交用户信息(此方法可以不调用)
// registerUser(country, phone);
}
}
});
registerPage.show(this);
*/
②.验证码页面
/**
* Created by asus on 2016/10/30.
*/
public class RegSecondActivity extends AppCompatActivity {
@ViewInject(R.id.toolbar)//toolbar
private CnToolbar mToolBar;
@ViewInject(R.id.txtTip)//验证码已发送的文字显示
private TextView mTxtTip;
@ViewInject(R.id.btn_reSend)//重新获取验证码的按钮
private Button mBtnResend;
@ViewInject(R.id.edittxt_code)//edittext验证码
private ClearEditText mEtCode;
private String phone;
private String pwd;
private String countryCode;
private SpotsDialog dialog;
private OkHttpHelper okHttpHelper = OkHttpHelper.getInstance();
private SMSEvenHanlder evenHanlder;
private CountTimerView countTimerView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reg_second);
ViewUtils.inject(this);
getMesFromRegActivity();//获取的电话.密码.国家区号
initSMSSDK();
initToolBar();//toolbar
initTexTip();//已发送短信到---text
initCountTimer();//定时器
}
/*1.初始化SMSSDK*/
private void initSMSSDK() {
SMSSDK.initSDK(this, Contants.APPKEY, Contants.APPSRECT);
evenHanlder = new SMSEvenHanlder();//自定义gui
SMSSDK.registerEventHandler(evenHanlder);//注册
dialog = new SpotsDialog(this);
dialog = new SpotsDialog(this, "正在校验验证码");
}
/*2.点击完成按钮提交服务器*/
private void submitCode() {
String vCode = mEtCode.getText().toString().trim();//验证码
if (TextUtils.isEmpty(vCode)) {
//如果为null返回
ToastUtil.showToast(this, R.string.smssdk_write_identify_code + "");
return;
}
//提交验证码验证(国家编号,电话,验证码)
SMSSDK.submitVerificationCode(countryCode, phone, vCode);
dialog.show();
}
/*3.sdk回调*/
class SMSEvenHanlder extends EventHandler {
@Override
public void afterEvent(final int event, final int result, final Object data) {
runOnUiThread(new Runnable() {
public void run() {
//回调的时候就隐藏dialog
if (dialog != null && dialog.isShowing())
dialog.dismiss();
Log.d("回调了","回调了2");
if (result == SMSSDK.RESULT_COMPLETE) {//如果请求完成之后
if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
/*4.验证成功,提交信息到注册服务器,或者执行另外操作*/
doReg();
dialog.setMessage("正在提交注册信息");
dialog.show();
}else{
if (dialog != null && dialog.isShowing())
dialog.dismiss();
ToastUtil.showToast(RegSecondActivity.this,"不是提交");
}
} else {
if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE
&& data != null
&& (data instanceof UserInterruptException)) {
// 由于此处是开发者自己决定要中断发送的,因此什么都不用做
ToastUtil.showToast(RegSecondActivity.this,"中断发送");
Log.d("回调了","中断发送");
return;
}
// 根据服务器返回的网络错误,给toast提示
if (dialog != null && dialog.isShowing())
dialog.dismiss();
ToastUtil.showToast(RegSecondActivity.this,"网络错误");
try {
((Throwable) data).printStackTrace();
Throwable throwable = (Throwable) data;
JSONObject object = new JSONObject(
throwable.getMessage());
String des = object.optString("detail");
if (!TextUtils.isEmpty(des)) {
ToastUtil.showToast(RegSecondActivity.this, des);
return;
}
} catch (Exception e) {
SMSLog.getInstance().w(e);
}
}
}
});
}
}
private void doReg() {
HashMap<String, Object> parmas = new HashMap<>(2);
parmas.put("phone", phone);
parmas.put("password", DESUtil.encode(Contants.DES_KEY, pwd));
okHttpHelper.post(Contants.API.REG,parmas, new SpotsCallBack<LoginRespMsg<User>>(this,false) {
@Override
public void onSuccess(Response response, LoginRespMsg<User> userLoginRespMsg) {
if(dialog !=null && dialog.isShowing())
dialog.dismiss();
if(userLoginRespMsg.getStatus()==LoginRespMsg.STATUS_ERROR){
ToastUtil.showToast(RegSecondActivity.this,"注册失败:"+userLoginRespMsg.getMessage());
startActivity(new Intent(RegSecondActivity.this,LoginActivity.class));
RegSecondActivity.this.finish();
return;
}
//保存数据 ( email,名字,等) 和 token
MyApplication application =MyApplication.getInstance();
application.putUser(userLoginRespMsg.getData(), userLoginRespMsg.getToken());
//回到MainActivity
startActivity(new Intent(RegSecondActivity.this,MainActivity.class));
finish();
}
@Override
public void onError(Response response, int code, Exception e) {
if(dialog !=null && dialog.isShowing())
dialog.dismiss();
//回到MainActivity
startActivity(new Intent(RegSecondActivity.this,MainActivity.class));
finish();
}
@Override
public void onTokenError(Response response, int code) {
super.onTokenError(response, code);
}
});
}
private void initToolBar() {
mToolBar.setRightButtonText("完成");
//完成按钮
mToolBar.setmRightImageButtonOnclickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
submitCode();//点击完成提交给服务器对比验证码
}
});
//上一步按钮
mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(RegSecondActivity.this,RegActivity.class));
finish();
}
});
}
//重新获取验证码
@OnClick(R.id.btn_reSend)
public void reSendCode(View view) {
SMSSDK.getVerificationCode("+" + countryCode, phone);//重新获取验证码
countTimerView = new CountTimerView(mBtnResend, R.string.smssdk_resend_identify_code);
countTimerView.start();
dialog.setMessage("正在重新获取验证码");
dialog.show();
}
private void initCountTimer() {
CountTimerView timerView = new CountTimerView(mBtnResend);
timerView.start();
}
private void getMesFromRegActivity() {
phone = getIntent().getStringExtra("phone");
pwd = getIntent().getStringExtra("pwd");
countryCode = getIntent().getStringExtra("countryCode");
}
private void initTexTip() {
String formatedPhone = "+" + countryCode + " " + splitPhoneNum(phone);
String text = getString(R.string.smssdk_send_mobile_detail) + formatedPhone;
mTxtTip.setText(Html.fromHtml(text));//将smssdk中的html格式代码进行格式化成字符串
}
/**
* 分割电话号码
*/
private String splitPhoneNum(String phone) {
StringBuilder builder = new StringBuilder(phone);
builder.reverse();
for (int i = 4, len = builder.length(); i < len; i += 5) {
builder.insert(i, ' ');
}
builder.reverse();
return builder.toString();
}
@Override
protected void onDestroy() {
super.onDestroy();
SMSSDK.unregisterEventHandler(evenHanlder);
}
}
③.按钮计时器
/**
* Created by asus on 2016/10/30.
*/
public class CountTimerView extends CountDownTimer {
public static final int TIME_COUNT = 61000;//时间防止从59s开始显示(以倒计时60s为例子)
private TextView btn;//传入进来的按钮(textView的子类是button)
private int endStrRid;//显示的文字
/**
* 参数 millisInFuture 倒计时总时间(如60S,120s等)
* 参数 countDownInterval 渐变时间(每次倒计1s)
* 参数 btn 点击的按钮(因为Button是TextView子类,为了通用我的参数设置为TextView)
* 参数 endStrRid 倒计时结束后,按钮对应显示的文字
*/
public CountTimerView(long millisInFuture, long countDownInterval, TextView btn, int endStrRid) {
super(millisInFuture, countDownInterval);
this.btn = btn;
this.endStrRid = endStrRid;
}
public CountTimerView(TextView btn, int endStrRid) {
super(TIME_COUNT, 1000);//设置总时间为61s,渐变1s
this.btn = btn;
this.endStrRid = endStrRid;
}
public CountTimerView(TextView btn) {
super(TIME_COUNT, 1000);
this.btn = btn;
this.endStrRid = R.string.smssdk_resend_identify_code;//重新获取验证码
}
//倒计时中
@Override
public void onTick(long millisUntilFinished) {
btn.setEnabled(false);
btn.setText(millisUntilFinished / 1000 + " 秒后可重新发送");
}
//倒计时完成调用
@Override
public void onFinish() {
btn.setText(endStrRid);
btn.setEnabled(true);
}
}