@@ -336,6 +336,19 @@ | |||
<activity android:name=".project.ui.activity.after.UndoLoopActivity" | |||
android:launchMode="singleTop" | |||
android:screenOrientation="portrait" /> | |||
<!--忘记密码第一步--> | |||
<activity android:name=".project.ui.activity.user.ForgetPwdStep1Activity" | |||
android:launchMode="singleTop" | |||
android:screenOrientation="portrait" /> | |||
<!--忘记密码第二步--> | |||
<activity android:name=".project.ui.activity.user.ForgetPwdStep2Activity" | |||
android:windowSoftInputMode="adjustPan" | |||
android:launchMode="singleTop" | |||
android:screenOrientation="portrait" /> | |||
<!--忘记密码第三步--> | |||
<activity android:name=".project.ui.activity.user.ForgetPwdStep3Activity" | |||
android:launchMode="singleTop" | |||
android:screenOrientation="portrait" /> | |||
</application> | |||
</manifest> |
@@ -28,6 +28,7 @@ public class IFCode { | |||
// 定义Map常量2 | |||
public static final Map<String, String> LoadingMsgMap = new HashMap<String, String>(); | |||
static { | |||
LoadingMsgMap.put(IFCode.IFCODE2, "发送中..."); | |||
LoadingMsgMap.put(IFCode.IFCODE4, "登录中..."); | |||
LoadingMsgMap.put(IFCode.IFCODE5, "登录中..."); | |||
LoadingMsgMap.put(IFCode.IFCODE6, "创建订单中..."); | |||
@@ -62,6 +63,7 @@ public class IFCode { | |||
LoadingMsgMap.put(IFCode.IFCODE78, "VFJ-修改车辆信息中..."); | |||
} | |||
public static final String IFCODE2 = "2"; //统一会员平台发送验证码接口 | |||
public static final String IFCODE4 = "4"; //登录 | |||
public static final String IFCODE5 = "5"; //通过code换取appid | |||
public static final String IFCODE6 = "6"; //创建订单 |
@@ -410,6 +410,7 @@ public class TopEntrapmentActivity extends AppActivity implements INRechargeChoo | |||
toast("请输入充值金额,或者选择需要充值的金额!"); | |||
return; | |||
} | |||
//TODO 测试注释 正式需放开 | |||
// if(Double.parseDouble(FunHelper.getText(binding.etInputMoney)) < 10){ | |||
// toast("最低充值金额不小于10元!"); | |||
// return; |
@@ -0,0 +1,62 @@ | |||
package com.huntersun.vkyes.etcopencard.project.ui.activity.user; | |||
import android.os.Bundle; | |||
import android.view.View; | |||
import com.huntersun.vky.obublelib.util.ValidatorUtils; | |||
import com.huntersun.vkyes.etcopencard.databinding.ActivityForgetPwdStep1Binding; | |||
import com.huntersun.vkyes.etcopencard.project.utils.FunHelper; | |||
import com.huntersun.vkyes.etcopencard.src.app.AppActivity; | |||
/** | |||
* Date :2023-03-14 | |||
* Description:忘记密码第一步 | |||
*/ | |||
public class ForgetPwdStep1Activity extends AppActivity { | |||
private ActivityForgetPwdStep1Binding binding; | |||
private String phone; | |||
@Override | |||
protected View getLayoutView() { | |||
binding = ActivityForgetPwdStep1Binding.inflate(getLayoutInflater()); | |||
return binding.getRoot(); | |||
} | |||
@Override | |||
protected void initView() { | |||
phone = getIntent().getStringExtra("phone"); | |||
if (!FunHelper.isEmpty(phone)){ | |||
binding.etLoginPhone.setText(phone); | |||
} | |||
initClick(); | |||
} | |||
@Override | |||
protected void initData() { | |||
} | |||
private void initClick(){ | |||
binding.btnConfirm.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View view) { | |||
String phone = FunHelper.getText(binding.etLoginPhone); | |||
if(FunHelper.isEmpty(phone)){ | |||
toast("请输入手机号!"); | |||
return; | |||
} | |||
if(!ValidatorUtils.isMobile(phone)){ | |||
toast("请输入正确的手机号!"); | |||
return; | |||
} | |||
Bundle bundle = new Bundle(); | |||
bundle.putString("phone",phone); | |||
jumpToPage(ForgetPwdStep2Activity.class,bundle); | |||
finish(); | |||
} | |||
}); | |||
} | |||
} |
@@ -0,0 +1,147 @@ | |||
package com.huntersun.vkyes.etcopencard.project.ui.activity.user; | |||
import android.os.Bundle; | |||
import android.util.Log; | |||
import android.view.View; | |||
import com.blankj.utilcode.util.LogUtils; | |||
import com.google.gson.Gson; | |||
import com.huntersun.vkyes.etcopencard.databinding.ActivityForgetPwdStep1Binding; | |||
import com.huntersun.vkyes.etcopencard.databinding.ActivityForgetPwdStep2Binding; | |||
import com.huntersun.vkyes.etcopencard.project.api.MyRetrofit; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.IFCode; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.ResultBean; | |||
import com.huntersun.vkyes.etcopencard.project.tool.MyShared; | |||
import com.huntersun.vkyes.etcopencard.project.ui.activity.MainActivity; | |||
import com.huntersun.vkyes.etcopencard.project.utils.FunHelper; | |||
import com.huntersun.vkyes.etcopencard.src.app.AppActivity; | |||
import com.huntersun.vkyes.etcopencard.src.other.CountDownTimerUtils; | |||
import com.jeremyliao.liveeventbus.LiveEventBus; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
/** | |||
* Date :2023-03-14 | |||
* Description:忘记密码第二步 | |||
*/ | |||
public class ForgetPwdStep2Activity extends AppActivity { | |||
private ActivityForgetPwdStep2Binding binding; | |||
//获取验证码倒计时 | |||
private CountDownTimerUtils codeCountDownTimer; | |||
//手机号 | |||
private String phone; | |||
@Override | |||
protected View getLayoutView() { | |||
binding = ActivityForgetPwdStep2Binding.inflate(getLayoutInflater()); | |||
return binding.getRoot(); | |||
} | |||
@Override | |||
protected void initView() { | |||
LiveEventBus.get("countDownFinish", Boolean.class) .observe(this, s -> {//倒计时结束 | |||
clearCountDown(true); | |||
}); | |||
phone = getIntent().getStringExtra("phone"); | |||
binding.tvPhone.setText("验证码已发送至:" + FunHelper.setPhoneSpace(phone)); | |||
binding.btnConfirm.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View view) { | |||
checkParams(); | |||
} | |||
}); | |||
binding.tvCountDownTime.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View view) { | |||
sendCode(); | |||
} | |||
}); | |||
} | |||
@Override | |||
protected void initData() { | |||
if (FunHelper.isEmpty(phone)){ | |||
toast("手机号为空!"); | |||
return; | |||
} | |||
sendCode(); | |||
} | |||
/* | |||
* 检测参数 | |||
*/ | |||
private void checkParams(){ | |||
if(FunHelper.isEmpty(binding.verPwd.getInputContent())){ | |||
toast("请输入验证码"); | |||
return; | |||
} | |||
if (binding.verPwd.getInputContent().length() != 6){ | |||
toast("请输入正确的验证码"); | |||
return; | |||
} | |||
Bundle bundle = new Bundle(); | |||
bundle.putString("phone", phone); | |||
bundle.putString("code",binding.verPwd.getInputContent()); | |||
jumpToPage(ForgetPwdStep3Activity.class,bundle); | |||
finish(); | |||
} | |||
/* | |||
* 发送验证码 | |||
*/ | |||
private void sendCode(){ | |||
showDialog("发送中..."); | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("mobile", phone); | |||
MyRetrofit.newInstance(IFCode.IFCODE2, params, new MyRetrofit.ReturnResult() { | |||
@Override | |||
public void onSuccess(ResultBean resultBean, ResultBean.BizContent bizContent) { | |||
hideDialog(); | |||
toast("验证码发送成功!"); | |||
FunHelper.showInputMethod(binding.verPwd.getEditText(),ForgetPwdStep2Activity.this); | |||
showTimeCountDown(60*1000); | |||
} | |||
@Override | |||
public void onError() { | |||
MyRetrofit.ReturnResult.super.onError(); | |||
hideDialog(); | |||
} | |||
}); | |||
} | |||
/* | |||
* 显示订单处理倒计时 | |||
*/ | |||
private void showTimeCountDown(long end_second) { | |||
if (end_second <= 0) return; | |||
codeCountDownTimer = new CountDownTimerUtils(this, null,null,null,binding.tvCountDownTime, end_second, 1000, false); | |||
codeCountDownTimer.start(); | |||
} | |||
/* | |||
* 清除订单处理倒计时 | |||
* reSend:是否重新发送验证码 | |||
*/ | |||
private void clearCountDown(boolean reSend) { | |||
if (codeCountDownTimer != null) { | |||
codeCountDownTimer.cancel(); | |||
codeCountDownTimer = null; | |||
} | |||
if (reSend){ | |||
binding.tvCountDownTime.setText("点击重新发送验证码"); | |||
} | |||
} | |||
@Override | |||
protected void onDestroy() { | |||
super.onDestroy(); | |||
clearCountDown(false); | |||
} | |||
} |
@@ -0,0 +1,109 @@ | |||
package com.huntersun.vkyes.etcopencard.project.ui.activity.user; | |||
import android.os.Bundle; | |||
import android.view.View; | |||
import com.huntersun.vkyes.etcopencard.databinding.ActivityForgetPwdStep3Binding; | |||
import com.huntersun.vkyes.etcopencard.project.api.MyRetrofit; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.IFCode; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.ResultBean; | |||
import com.huntersun.vkyes.etcopencard.project.utils.FunHelper; | |||
import com.huntersun.vkyes.etcopencard.src.app.AppActivity; | |||
import com.huntersun.vkyes.etcopencard.src.ui.activity.LoginActivity; | |||
import com.jeremyliao.liveeventbus.LiveEventBus; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
/** | |||
* Date :2023-03-14 | |||
* Description:忘记密码第三步 | |||
*/ | |||
public class ForgetPwdStep3Activity extends AppActivity { | |||
private ActivityForgetPwdStep3Binding binding; | |||
//上个界面传递的手机号和验证码 | |||
private String phone; | |||
private String code; | |||
@Override | |||
protected View getLayoutView() { | |||
binding = ActivityForgetPwdStep3Binding.inflate(getLayoutInflater()); | |||
return binding.getRoot(); | |||
} | |||
@Override | |||
protected void initView() { | |||
phone = getIntent().getStringExtra("phone"); | |||
code = getIntent().getStringExtra("code"); | |||
binding.btnConfirm.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View view) { | |||
checkParams(); | |||
} | |||
}); | |||
} | |||
@Override | |||
protected void initData() { | |||
} | |||
/* | |||
* 检查参数 | |||
*/ | |||
private void checkParams(){ | |||
String pwd = FunHelper.getText(binding.etPassword); | |||
String againPwd = FunHelper.getText(binding.etAgainPassword); | |||
if (FunHelper.isEmpty(pwd)){ | |||
toast("请设置密码"); | |||
return; | |||
} | |||
if (FunHelper.isEmpty(againPwd)){ | |||
toast("请再次输入密码"); | |||
return; | |||
} | |||
if (!pwd.equals(againPwd)){ | |||
toast("两次密码输入不一致,请重新输入"); | |||
return; | |||
} | |||
toResetPwd(); | |||
} | |||
/* | |||
* 修改密码 | |||
*/ | |||
private void toResetPwd(){ | |||
showDialog("密码重置中..."); | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("mobile", phone); | |||
params.put("verificationCode", code); | |||
params.put("password", FunHelper.getText(binding.etPassword)); | |||
params.put("affirmPassword", FunHelper.getText(binding.etAgainPassword)); | |||
MyRetrofit.newInstance(IFCode.IFCODE52, params, new MyRetrofit.ReturnResult() { | |||
@Override | |||
public void onSuccess(ResultBean resultBean, ResultBean.BizContent bizContent) { | |||
hideDialog(); | |||
toast("密码修改成功,请重新登录!"); | |||
LiveEventBus.get("updatePwdSuccess").post(true); | |||
Bundle bundle = new Bundle(); | |||
bundle.putString("phone",phone); | |||
bundle.putString("pwd",FunHelper.getText(binding.etPassword)); | |||
jumpToPage(LoginActivity.class,bundle); | |||
finish(); | |||
} | |||
@Override | |||
public void onError() { | |||
MyRetrofit.ReturnResult.super.onError(); | |||
hideDialog(); | |||
} | |||
}); | |||
} | |||
} |
@@ -1,12 +1,18 @@ | |||
package com.huntersun.vkyes.etcopencard.project.utils; | |||
import android.app.Activity; | |||
import android.content.Context; | |||
import android.text.SpannableString; | |||
import android.text.Spanned; | |||
import android.text.style.ForegroundColorSpan; | |||
import android.view.View; | |||
import android.view.inputmethod.InputMethodManager; | |||
import android.widget.EditText; | |||
import android.widget.TextView; | |||
import java.util.List; | |||
import java.util.Timer; | |||
import java.util.TimerTask; | |||
import java.util.regex.Matcher; | |||
import java.util.regex.Pattern; | |||
@@ -230,4 +236,58 @@ public class FunHelper { | |||
return isMatch; | |||
} | |||
/* | |||
* 给手机号添加空格 | |||
* | |||
* @param mobile | |||
* @return | |||
*/ | |||
public static String setPhoneSpace(String mobile) { | |||
if (isEmpty(mobile)){ | |||
return ""; | |||
} | |||
if (mobile.length() != 11){ | |||
return mobile; | |||
} | |||
StringBuilder builder = new StringBuilder(); | |||
for (int i = 0; i < mobile.length(); i++){ | |||
if (i < 2){ | |||
builder.append(mobile.charAt(i)); | |||
}else if (i == 2){ | |||
builder.append(mobile.charAt(i)).append(' '); | |||
}else if (i > 3 && i < 6){ | |||
builder.append(mobile.charAt(i)); | |||
}else if ( i == 6){ | |||
builder.append(mobile.charAt(i)).append(' '); | |||
}else{ | |||
builder.append(mobile.charAt(i)); | |||
} | |||
} | |||
return builder.toString(); | |||
} | |||
/* | |||
* 弹出软键盘 | |||
* | |||
* @param editText | |||
* @param activity | |||
*/ | |||
public static void showInputMethod(EditText editText, Activity activity){ | |||
editText.setFocusable(true); | |||
editText.setFocusableInTouchMode(true); | |||
editText.requestFocus(); | |||
Timer timer = new Timer(); | |||
timer.schedule(new TimerTask() { | |||
@Override | |||
public void run() { | |||
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); | |||
imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED); | |||
} | |||
}, 100); | |||
} | |||
} |
@@ -0,0 +1,177 @@ | |||
package com.huntersun.vkyes.etcopencard.src.other; | |||
import android.content.Context; | |||
import android.os.CountDownTimer; | |||
import android.widget.TextView; | |||
import com.huntersun.vkyes.etcopencard.project.utils.FunHelper; | |||
import com.jeremyliao.liveeventbus.LiveEventBus; | |||
/** | |||
* Date :2023-03-14 | |||
* Description:倒计时工具类 | |||
*/ | |||
public class CountDownTimerUtils extends CountDownTimer { | |||
private Context context; | |||
private TextView tvDay; | |||
private TextView tvHour; | |||
private TextView tvMin; | |||
private TextView tvSec; | |||
private TextView tvHMS; | |||
private boolean isShowDay = false; | |||
private String hint; | |||
private String beforeHint; //时间前提示信息 | |||
private String afterHint;//时间后提示时间 | |||
public CountDownTimerUtils(Context context, | |||
TextView tvHour, | |||
TextView tvMin, | |||
TextView tvSec, | |||
int eventType, | |||
long millisInFuture, | |||
long countDownInterval) { | |||
super(millisInFuture, countDownInterval); | |||
this.context = context; | |||
this.tvHour = tvHour; | |||
this.tvMin = tvMin; | |||
this.tvSec = tvSec; | |||
this.isShowDay = false; | |||
} | |||
public CountDownTimerUtils(Context context, | |||
TextView tvDay, | |||
TextView tvHour, | |||
TextView tvMin, | |||
TextView tvSec, | |||
long millisInFuture, | |||
long countDownInterval, | |||
boolean isShowDay) { | |||
super(millisInFuture, countDownInterval); | |||
this.context = context; | |||
this.tvDay = tvDay; | |||
this.tvHour = tvHour; | |||
this.tvMin = tvMin; | |||
this.tvSec = tvSec; | |||
this.isShowDay = isShowDay; | |||
} | |||
public CountDownTimerUtils(Context context, | |||
TextView tvHMS, | |||
String hint, | |||
long millisInFuture, | |||
long countDownInterval, | |||
boolean isShowDay) { | |||
super(millisInFuture, countDownInterval); | |||
this.context = context; | |||
this.tvHMS = tvHMS; | |||
this.hint = hint; | |||
this.isShowDay = isShowDay; | |||
} | |||
@Override | |||
public void onTick(long millisUntilFinished) { | |||
DateBean bean = isShowDay ? getCountDownTimeWithDay(millisUntilFinished) | |||
: getCountDownTime(millisUntilFinished); | |||
if (beforeHint == null){ | |||
beforeHint = ""; | |||
} | |||
if (hint == null) { | |||
hint = ""; | |||
} | |||
if (afterHint == null) { | |||
afterHint = ""; | |||
} | |||
//显示普通的 HH:MM:SS / _HH:MM:SS | |||
if (tvHMS != null) { | |||
tvHMS.setText((FunHelper.isEmpty(beforeHint) ? hint : beforeHint) + bean.hour + ":" + bean.minute + ":" + bean.second + afterHint); | |||
return; | |||
} | |||
//时、分、秒各显示 | |||
if (isShowDay && tvDay != null) { | |||
tvDay.setText((FunHelper.isEmpty(beforeHint) ? hint : beforeHint) + bean.day); | |||
} | |||
if (tvHour != null) { | |||
tvHour.setText(bean.hour); | |||
} | |||
if (tvMin != null) { | |||
tvMin.setText(bean.minute); | |||
} | |||
if (tvSec != null) { | |||
tvSec.setText(((tvDay == null && tvHour == null && tvMin == null) ? beforeHint : "") + bean.second + afterHint); | |||
} | |||
} | |||
@Override | |||
public void onFinish() { | |||
LiveEventBus.get("countDownFinish").post(true); | |||
} | |||
/* | |||
* 获取倒计时(时分秒) | |||
* | |||
* @param time | |||
* @return | |||
*/ | |||
public static DateBean getCountDownTime(long time) { | |||
long second = time / 1000; | |||
long hour = second / 60 / 60; | |||
long minute = (second - hour * 60 * 60) / 60; | |||
long sec = (second - hour * 60 * 60) - minute * 60; | |||
String rHour = (hour < 10) ? "0" + hour : hour + ""; | |||
String rMin = (minute < 10) ? "0" + minute : minute + ""; | |||
String rSs = (sec < 10) ? "0" + sec : sec + ""; | |||
DateBean bean = new DateBean(); | |||
bean.hour = rHour; | |||
bean.minute = rMin; | |||
bean.second = rSs; | |||
return bean; | |||
} | |||
/* | |||
* 获取倒计时(天时分秒) | |||
* | |||
* @param time | |||
* @return | |||
*/ | |||
public static DateBean getCountDownTimeWithDay(long time) { | |||
long second = time / 1000; | |||
long day = second / 60 / 60 / 24; | |||
long hour = (second - day * 24 * 3600) / 3600; | |||
long minute = ((second - day * 24 * 3600) - (hour * 3600)) / 60; | |||
long sec = (second - day * 24 * 3600) - hour * 3600 - minute * 60; | |||
String rDay = (day < 10) ? "0" + day : day + ""; | |||
String rHour = (hour < 10) ? "0" + hour : hour + ""; | |||
String rMin = (minute < 10) ? "0" + minute : minute + ""; | |||
String rSs = (sec < 10) ? "0" + sec : sec + ""; | |||
DateBean bean = new DateBean(); | |||
bean.day = rDay; | |||
bean.hour = rHour; | |||
bean.minute = rMin; | |||
bean.second = rSs; | |||
return bean; | |||
} | |||
static class DateBean { | |||
public String day; | |||
public String hour; | |||
public String minute; | |||
public String second; | |||
} | |||
} | |||
@@ -6,9 +6,7 @@ import android.annotation.SuppressLint; | |||
import android.app.Activity; | |||
import android.content.Context; | |||
import android.content.Intent; | |||
import android.util.Base64; | |||
import android.util.Log; | |||
import android.view.Gravity; | |||
import android.os.Bundle; | |||
import android.view.KeyEvent; | |||
import android.view.View; | |||
import android.view.ViewGroup; | |||
@@ -20,16 +18,11 @@ import android.widget.ImageView; | |||
import android.widget.LinearLayout; | |||
import android.widget.TextView; | |||
import androidx.annotation.NonNull; | |||
import androidx.annotation.Nullable; | |||
import com.blankj.utilcode.util.ConvertUtils; | |||
import com.blankj.utilcode.util.EncodeUtils; | |||
import com.blankj.utilcode.util.EncryptUtils; | |||
import com.google.gson.Gson; | |||
import com.gyf.immersionbar.ImmersionBar; | |||
import com.hjq.base.BaseDialog; | |||
import com.hjq.umeng.UmengClient; | |||
import com.hjq.widget.view.CountdownView; | |||
import com.hjq.widget.view.SubmitButton; | |||
import com.huntersun.vkyes.etcopencard.R; | |||
import com.huntersun.vkyes.etcopencard.project.api.Api; | |||
import com.huntersun.vkyes.etcopencard.project.api.Converter; | |||
@@ -38,34 +31,24 @@ import com.huntersun.vkyes.etcopencard.project.api.MyRetrofit; | |||
import com.huntersun.vkyes.etcopencard.project.api.RequestParameters; | |||
import com.huntersun.vkyes.etcopencard.project.api.Result; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.IFCode; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.LoginBean; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.ResultBean; | |||
import com.huntersun.vkyes.etcopencard.project.api.bean.SendTheVerificationCodeBean; | |||
import com.huntersun.vkyes.etcopencard.project.tool.MyShared; | |||
import com.huntersun.vkyes.etcopencard.project.tool.RSAUtil; | |||
import com.huntersun.vkyes.etcopencard.project.tool.Utils; | |||
import com.huntersun.vkyes.etcopencard.project.ui.activity.MainActivity; | |||
import com.huntersun.vkyes.etcopencard.project.ui.activity.UpdatePasswordActivity; | |||
import com.huntersun.vkyes.etcopencard.project.ui.activity.user.ForgetPwdStep1Activity; | |||
import com.huntersun.vkyes.etcopencard.project.utils.FunHelper; | |||
import com.huntersun.vkyes.etcopencard.src.aop.SingleClick; | |||
import com.huntersun.vkyes.etcopencard.src.app.AppActivity; | |||
import com.huntersun.vkyes.etcopencard.src.http.glide.GlideApp; | |||
import com.huntersun.vkyes.etcopencard.src.other.KeyboardWatcher; | |||
import com.huntersun.vkyes.etcopencard.src.ui.dialog.MenuDialog; | |||
import com.huntersun.vkyes.etcopencard.src.wxapi.WXEntryActivity; | |||
import com.hjq.umeng.Platform; | |||
import com.hjq.umeng.UmengClient; | |||
import com.hjq.umeng.UmengLogin; | |||
import com.hjq.widget.view.SubmitButton; | |||
import com.jeremyliao.liveeventbus.LiveEventBus; | |||
import java.security.PublicKey; | |||
import java.time.LocalDateTime; | |||
import java.time.format.DateTimeFormatter; | |||
import java.util.Arrays; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import retrofit2.Response; | |||
import androidx.annotation.NonNull; | |||
import androidx.annotation.Nullable; | |||
/** | |||
* author : Android 轮子哥 | |||
@@ -141,6 +124,27 @@ public final class LoginActivity extends AppActivity | |||
setOnClickListener(mForgetView, mCountdownView, mTvLoginCode, mCodeView, mCommitView); | |||
mPasswordView.setOnEditorActionListener(this); | |||
updatePwdSuccess(); | |||
} | |||
/** | |||
* 修改密码成功 | |||
*/ | |||
private void updatePwdSuccess(){ | |||
//修改密码之后-自动填充 | |||
String phone = getIntent().getStringExtra("phone"); | |||
String pwd = getIntent().getStringExtra("pwd"); | |||
if(!FunHelper.isEmpty(phone)){ | |||
mPhoneView.setText(phone); | |||
} | |||
if (!FunHelper.isEmpty(pwd)){ | |||
mPasswordView.setText(pwd); | |||
} | |||
LiveEventBus.get("updatePwdSuccess", Boolean.class) .observe(this, s -> { | |||
finish(); | |||
}); | |||
} | |||
@Override | |||
@@ -173,10 +177,14 @@ public final class LoginActivity extends AppActivity | |||
@Override | |||
public void onClick(View view) { | |||
if (view == mForgetView) { | |||
Intent intent = new Intent(); | |||
/* Intent intent = new Intent(); | |||
intent.putExtra("start", false); | |||
intent.setClass(LoginActivity.this, UpdatePasswordActivity.class); | |||
startActivity(intent); | |||
startActivity(intent);*/ | |||
Bundle bundle = new Bundle(); | |||
bundle.putString("phone",FunHelper.getText(mPhoneView)); | |||
jumpToPage(ForgetPwdStep1Activity.class,bundle); | |||
return; | |||
} | |||
@@ -225,10 +233,19 @@ public final class LoginActivity extends AppActivity | |||
toast(R.string.common_phone_input_error); | |||
return; | |||
} | |||
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); | |||
String value = loginStart ? mPasswordView.getText().toString() : mCodeView.getText().toString(); | |||
// 隐藏软键盘 | |||
hideKeyboard(getCurrentFocus()); | |||
if (FunHelper.isEmpty(value)){ | |||
toast("请输入密码!"); | |||
mPasswordView.startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.shake_anim)); | |||
mCommitView.showError(3000); | |||
return; | |||
} | |||
//提交数据处理 | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("mobile", mPhoneView.getText() + ""); | |||
@@ -334,4 +351,5 @@ public final class LoginActivity extends AppActivity | |||
// 指定导航栏背景颜色 | |||
.navigationBarColor(R.color.white); | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
package com.huntersun.vkyes.etcopencard.src.widget.vertfiycode; | |||
import android.content.Context; | |||
import android.util.AttributeSet; | |||
import android.view.inputmethod.EditorInfo; | |||
import android.view.inputmethod.InputConnection; | |||
import androidx.appcompat.widget.AppCompatEditText; | |||
/** | |||
* Date :2023-03-14 | |||
* Description:重写InputConnection 监听返回键 | |||
*/ | |||
public class PwdEditText extends AppCompatEditText { | |||
private TInputConnection inputConnection; | |||
public PwdEditText(Context context) { | |||
super(context); | |||
init(); | |||
} | |||
public PwdEditText(Context context, AttributeSet attrs) { | |||
super(context, attrs); | |||
init(); | |||
} | |||
public PwdEditText(Context context, AttributeSet attrs, int defStyleAttr) { | |||
super(context, attrs, defStyleAttr); | |||
init(); | |||
} | |||
private void init(){ | |||
inputConnection = new TInputConnection(null,true); | |||
} | |||
/** | |||
* 当输入法和EditText建立连接的时候会通过这个方法返回一个InputConnection。 | |||
* 我们需要代理这个方法的父类方法生成的InputConnection并返回我们自己的代理类。 | |||
* */ | |||
@Override | |||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) { | |||
inputConnection.setTarget(super.onCreateInputConnection(outAttrs)); | |||
return inputConnection; | |||
} | |||
public void setBackSpaceListener(TInputConnection.BackspaceListener backSpaceLisetener){ | |||
inputConnection.setBackspaceListener(backSpaceLisetener); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
package com.huntersun.vkyes.etcopencard.src.widget.vertfiycode; | |||
import android.content.Context; | |||
import android.graphics.Canvas; | |||
import android.graphics.Color; | |||
import android.graphics.Paint; | |||
import android.util.AttributeSet; | |||
import androidx.appcompat.widget.AppCompatTextView; | |||
/** | |||
* Date :2023-03-14 | |||
* Description: | |||
*/ | |||
public class PwdTextView extends AppCompatTextView { | |||
private float radius; | |||
private boolean hasPwd; | |||
public PwdTextView(Context context) { | |||
this(context, null); | |||
} | |||
public PwdTextView(Context context, AttributeSet attrs) { | |||
this(context, attrs, 0); | |||
} | |||
public PwdTextView(Context context, AttributeSet attrs, int defStyleAttr) { | |||
super(context, attrs, defStyleAttr); | |||
} | |||
@Override | |||
protected void onDraw(Canvas canvas) { | |||
super.onDraw(canvas); | |||
if (hasPwd) { | |||
// 画一个黑色的圆 | |||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); | |||
paint.setColor(Color.BLACK); | |||
paint.setStyle(Paint.Style.FILL); | |||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint); | |||
} | |||
} | |||
public void clearPwd() { | |||
this.hasPwd = false; | |||
invalidate(); | |||
} | |||
public void drawPwd(float radius) { | |||
this.hasPwd = true; | |||
if (radius == 0) { | |||
this.radius = getWidth() / 4; | |||
} else { | |||
this.radius = radius; | |||
} | |||
invalidate(); | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
package com.huntersun.vkyes.etcopencard.src.widget.vertfiycode; | |||
import android.view.KeyEvent; | |||
import android.view.inputmethod.InputConnection; | |||
import android.view.inputmethod.InputConnectionWrapper; | |||
/** | |||
* Date :2023-03-14 | |||
* Description: | |||
*/ | |||
public class TInputConnection extends InputConnectionWrapper { | |||
private BackspaceListener mBackspaceListener; | |||
/** | |||
* Initializes a wrapper. | |||
* <p> | |||
* <p><b>Caveat:</b> Although the system can accept {@code (InputConnection) null} in some | |||
* places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that | |||
* has {@code null} in {@code target}.</p> | |||
* | |||
* @param target the {@link InputConnection} to be proxied. | |||
* @param mutable set {@code true} to protect this object from being reconfigured to target | |||
* another {@link InputConnection}. Note that this is ignored while the target is {@code null}. | |||
*/ | |||
public TInputConnection(InputConnection target, boolean mutable) { | |||
super(target, mutable); | |||
} | |||
public interface BackspaceListener { | |||
/** | |||
* @return true 代表消费了这个事件 | |||
* */ | |||
boolean onBackspace(); | |||
} | |||
/** | |||
* 当软键盘删除文本之前,会调用这个方法通知输入框,我们可以重写这个方法并判断是否要拦截这个删除事件。 | |||
* 在谷歌输入法上,点击退格键的时候不会调用{@link #sendKeyEvent(KeyEvent event)}, | |||
* 而是直接回调这个方法,所以也要在这个方法上做拦截; | |||
* */ | |||
@Override | |||
public boolean deleteSurroundingText(int beforeLength, int afterLength) { | |||
if(mBackspaceListener != null){ | |||
if(mBackspaceListener.onBackspace()){ | |||
return true; | |||
} | |||
} | |||
return super.deleteSurroundingText(beforeLength, afterLength); | |||
} | |||
public void setBackspaceListener(BackspaceListener backspaceListener) { | |||
this.mBackspaceListener = backspaceListener; | |||
} | |||
/** | |||
* 当在软件盘上点击某些按钮(比如退格键,数字键,回车键等),该方法可能会被触发(取决于输入法的开发者), | |||
* 所以也可以重写该方法并拦截这些事件,这些事件就不会被分发到输入框了 | |||
* */ | |||
@Override | |||
public boolean sendKeyEvent(KeyEvent event) { | |||
if( event.getKeyCode() == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN){ | |||
if(mBackspaceListener != null && mBackspaceListener.onBackspace()){ | |||
return true; | |||
} | |||
} | |||
return super.sendKeyEvent(event); | |||
} | |||
} |
@@ -0,0 +1,361 @@ | |||
package com.huntersun.vkyes.etcopencard.src.widget.vertfiycode; | |||
import android.content.Context; | |||
import android.content.res.TypedArray; | |||
import android.graphics.Color; | |||
import android.graphics.drawable.Drawable; | |||
import android.text.Editable; | |||
import android.text.InputFilter; | |||
import android.text.TextUtils; | |||
import android.text.TextWatcher; | |||
import android.util.AttributeSet; | |||
import android.util.TypedValue; | |||
import android.view.Gravity; | |||
import android.view.KeyEvent; | |||
import android.view.LayoutInflater; | |||
import android.view.View; | |||
import android.widget.EditText; | |||
import android.widget.LinearLayout; | |||
import android.widget.RelativeLayout; | |||
import android.widget.TextView; | |||
import com.huntersun.vkyes.etcopencard.R; | |||
/** | |||
* Date :2023-03-14 | |||
* Description:自定义验证码输入框 | |||
*/ | |||
public class VerificationCodeView extends RelativeLayout { | |||
private LinearLayout containerEt; | |||
private PwdEditText et; | |||
// 输入框数量 | |||
private int mEtNumber; | |||
// 输入框的宽度 | |||
private int mEtWidth; | |||
//输入框分割线 | |||
private Drawable mEtDividerDrawable; | |||
//输入框文字颜色 | |||
private int mEtTextColor; | |||
//输入框文字大小 | |||
private float mEtTextSize; | |||
//输入框获取焦点时背景 | |||
private Drawable mEtBackgroundDrawableFocus; | |||
//输入框没有焦点时背景 | |||
private Drawable mEtBackgroundDrawableNormal; | |||
//是否是密码模式 | |||
private boolean mEtPwd; | |||
//密码模式时圆的半径 | |||
private float mEtPwdRadius; | |||
//存储TextView的数据 数量由自定义控件的属性传入 | |||
private PwdTextView[] mPwdTextViews; | |||
private MyTextWatcher myTextWatcher = new MyTextWatcher(); | |||
public VerificationCodeView(Context context) { | |||
this(context, null); | |||
} | |||
public VerificationCodeView(Context context, AttributeSet attrs) { | |||
this(context, attrs, 0); | |||
} | |||
public VerificationCodeView(Context context, AttributeSet attrs, int defStyleAttr) { | |||
super(context, attrs, defStyleAttr); | |||
init(context, attrs, defStyleAttr); | |||
} | |||
//初始化 布局和属性 | |||
private void init(Context context, AttributeSet attrs, int defStyleAttr) { | |||
LayoutInflater.from(context).inflate(R.layout.layout_identifying_code, this); | |||
containerEt = (LinearLayout) this.findViewById(R.id.container_et); | |||
et = (PwdEditText) this.findViewById(R.id.et); | |||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VerificationCodeView, defStyleAttr, 0); | |||
mEtNumber = typedArray.getInteger(R.styleable.VerificationCodeView_icv_et_number, 1); | |||
mEtWidth = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_width, 45); | |||
mEtDividerDrawable = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_divider_drawable); | |||
mEtTextSize = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_text_size, (int) sp2px(16, context)); | |||
mEtTextColor = typedArray.getColor(R.styleable.VerificationCodeView_icv_et_text_color, Color.BLACK); | |||
mEtBackgroundDrawableFocus = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_bg_focus); | |||
mEtBackgroundDrawableNormal = typedArray.getDrawable(R.styleable.VerificationCodeView_icv_et_bg_normal); | |||
mEtPwd = typedArray.getBoolean(R.styleable.VerificationCodeView_icv_et_pwd, false); | |||
mEtPwdRadius = typedArray.getDimensionPixelSize(R.styleable.VerificationCodeView_icv_et_pwd_radius, 0); | |||
//释放资源 | |||
typedArray.recycle(); | |||
// 当xml中未配置时 这里进行初始配置默认图片 | |||
if (mEtDividerDrawable == null) { | |||
mEtDividerDrawable = context.getResources().getDrawable(R.drawable.shape_divider_identifying); | |||
} | |||
if (mEtBackgroundDrawableFocus == null) { | |||
mEtBackgroundDrawableFocus = context.getResources().getDrawable(R.drawable.shape_icv_et_bg_focus); | |||
} | |||
if (mEtBackgroundDrawableNormal == null) { | |||
mEtBackgroundDrawableNormal = context.getResources().getDrawable(R.drawable.shape_icv_et_bg_normal); | |||
} | |||
initUI(); | |||
} | |||
// 初始UI | |||
private void initUI() { | |||
initTextViews(getContext(), mEtNumber, mEtWidth, mEtDividerDrawable, mEtTextSize, mEtTextColor); | |||
initEtContainer(mPwdTextViews); | |||
setListener(); | |||
} | |||
@Override | |||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |||
// 设置当 高为 warpContent 模式时的默认值 为 50dp | |||
int mHeightMeasureSpec = heightMeasureSpec; | |||
int heightMode = MeasureSpec.getMode(mHeightMeasureSpec); | |||
if (heightMode == MeasureSpec.AT_MOST) { | |||
mHeightMeasureSpec = MeasureSpec.makeMeasureSpec((int) dp2px(50, getContext()), MeasureSpec.EXACTLY); | |||
} | |||
super.onMeasure(widthMeasureSpec, mHeightMeasureSpec); | |||
} | |||
//初始化TextView | |||
private void initTextViews(Context context, int etNumber, int etWidth, Drawable etDividerDrawable, float etTextSize, int etTextColor) { | |||
// 设置 editText 的输入长度 | |||
et.setCursorVisible(false);//将光标隐藏 | |||
et.setFilters(new InputFilter[]{new InputFilter.LengthFilter(etNumber)}); //最大输入长度 | |||
// 设置分割线的宽度 | |||
if (etDividerDrawable != null) { | |||
etDividerDrawable.setBounds(0, 0, etDividerDrawable.getMinimumWidth(), etDividerDrawable.getMinimumHeight()); | |||
containerEt.setDividerDrawable(etDividerDrawable); | |||
} | |||
mPwdTextViews = new PwdTextView[etNumber]; | |||
for (int i = 0; i < mPwdTextViews.length; i++) { | |||
PwdTextView textView = new PwdTextView(context); | |||
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, etTextSize); | |||
textView.setTextColor(etTextColor); | |||
textView.setWidth(etWidth); | |||
textView.setHeight(etWidth); | |||
if (i == 0) { | |||
textView.setBackgroundDrawable(mEtBackgroundDrawableFocus); | |||
} else { | |||
textView.setBackgroundDrawable(mEtBackgroundDrawableNormal); | |||
} | |||
textView.setGravity(Gravity.CENTER); | |||
textView.setFocusable(false); | |||
mPwdTextViews[i] = textView; | |||
} | |||
} | |||
//初始化存储TextView 的容器 | |||
private void initEtContainer(TextView[] mTextViews) { | |||
for (TextView mTextView : mTextViews) { | |||
containerEt.addView(mTextView); | |||
} | |||
} | |||
private void setListener() { | |||
// 监听输入内容 | |||
et.addTextChangedListener(myTextWatcher); | |||
// 监听删除按键 | |||
et.setOnKeyListener(new OnKeyListener() { | |||
@Override | |||
public boolean onKey(View v, int keyCode, KeyEvent event) { | |||
if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) { | |||
onKeyDelete(); | |||
return true; | |||
} | |||
return false; | |||
} | |||
}); | |||
} | |||
// 给TextView 设置文字 | |||
private void setText(String inputContent) { | |||
for (int i = 0; i < mPwdTextViews.length; i++) { | |||
PwdTextView tv = mPwdTextViews[i]; | |||
if (tv.getText().toString().trim().equals("")) { | |||
if (mEtPwd) { | |||
tv.drawPwd(mEtPwdRadius); | |||
tv.setTextColor(getResources().getColor(R.color.transparent)); | |||
}else{ | |||
tv.setTextColor(mEtTextColor); | |||
} | |||
tv.setText(inputContent); | |||
// 添加输入完成的监听 | |||
if (inputCompleteListener != null) { | |||
inputCompleteListener.inputComplete(); | |||
} | |||
tv.setBackgroundDrawable(mEtBackgroundDrawableNormal); | |||
if (i < mEtNumber - 1) { | |||
mPwdTextViews[i + 1].setBackgroundDrawable(mEtBackgroundDrawableFocus); | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
// 监听删除 | |||
private void onKeyDelete() { | |||
for (int i = mPwdTextViews.length - 1; i >= 0; i--) { | |||
PwdTextView tv = mPwdTextViews[i]; | |||
if (!tv.getText().toString().trim().equals("")) { | |||
if (mEtPwd) { | |||
tv.clearPwd(); | |||
} | |||
tv.setText(""); | |||
// 添加删除完成监听 | |||
if (inputCompleteListener != null) { | |||
inputCompleteListener.deleteContent(); | |||
} | |||
tv.setBackgroundDrawable(mEtBackgroundDrawableFocus); | |||
if (i < mEtNumber - 1) { | |||
mPwdTextViews[i + 1].setBackgroundDrawable(mEtBackgroundDrawableNormal); | |||
} | |||
break; | |||
} | |||
} | |||
} | |||
/* | |||
* 获取输入文本 | |||
* | |||
* @return string | |||
*/ | |||
public String getInputContent() { | |||
StringBuffer buffer = new StringBuffer(); | |||
for (TextView tv : mPwdTextViews) { | |||
buffer.append(tv.getText().toString().trim()); | |||
} | |||
return buffer.toString(); | |||
} | |||
/* | |||
* 删除输入内容 | |||
*/ | |||
public void clearInputContent() { | |||
for (int i = 0; i < mPwdTextViews.length; i++) { | |||
if (i == 0) { | |||
mPwdTextViews[i].setBackgroundDrawable(mEtBackgroundDrawableFocus); | |||
} else { | |||
mPwdTextViews[i].setBackgroundDrawable(mEtBackgroundDrawableNormal); | |||
} | |||
if (mEtPwd) { | |||
mPwdTextViews[i].clearPwd(); | |||
} | |||
mPwdTextViews[i].setText(""); | |||
} | |||
} | |||
/* | |||
* 设置输入框个数 | |||
* | |||
* @param etNumber | |||
*/ | |||
public void setEtNumber(int etNumber) { | |||
this.mEtNumber = etNumber; | |||
et.removeTextChangedListener(myTextWatcher); | |||
containerEt.removeAllViews(); | |||
initUI(); | |||
} | |||
/* | |||
* 获取输入的位数 | |||
* | |||
* @return int | |||
*/ | |||
public int getEtNumber() { | |||
return mEtNumber; | |||
} | |||
/* | |||
* 设置是否是密码模式 默认不是 | |||
* | |||
* @param isPwdMode | |||
*/ | |||
public void setPwdMode(boolean isPwdMode) { | |||
this.mEtPwd = isPwdMode; | |||
} | |||
/* | |||
* 获取输入的EditText 用于外界设置键盘弹出 | |||
* | |||
* @return EditText | |||
*/ | |||
public EditText getEditText() { | |||
return et; | |||
} | |||
// 输入完成 和 删除成功 的监听 | |||
private InputCompleteListener inputCompleteListener; | |||
public void setInputCompleteListener(InputCompleteListener inputCompleteListener) { | |||
this.inputCompleteListener = inputCompleteListener; | |||
} | |||
public interface InputCompleteListener { | |||
void inputComplete(); | |||
void deleteContent(); | |||
} | |||
public float dp2px(float dpValue, Context context) { | |||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, | |||
dpValue, context.getResources().getDisplayMetrics()); | |||
} | |||
public float sp2px(float spValue, Context context) { | |||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, | |||
spValue, context.getResources().getDisplayMetrics()); | |||
} | |||
private class MyTextWatcher implements TextWatcher { | |||
@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 editable) { | |||
String inputStr = editable.toString(); | |||
if (!TextUtils.isEmpty(inputStr)) { | |||
String[] strArray = inputStr.split(""); | |||
for (int i = 0; i < strArray.length; i++) { | |||
// 不能大于输入框个数 | |||
if (i > mEtNumber) { | |||
break; | |||
} | |||
setText(strArray[i]); | |||
et.setText(""); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,7 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<shape xmlns:android="http://schemas.android.com/apk/res/android"> | |||
<size | |||
android:width="@dimen/dp_10" | |||
android:height="6dp" /> | |||
<solid android:color="#00000000" /> | |||
</shape> |
@@ -0,0 +1,28 @@ | |||
<!--<?xml version="1.0" encoding="utf-8"?>--> | |||
<!--<shape xmlns:android="http://schemas.android.com/apk/res/android"--> | |||
<!-- android:shape="rectangle">--> | |||
<!-- <solid android:color="@color/white" />--> | |||
<!-- <!– 大小 –>--> | |||
<!-- <size--> | |||
<!-- android:width="@dimen/dp_40"--> | |||
<!-- android:height="@dimen/dp_40" /><!– 宽度和高度 –>--> | |||
<!-- <corners android:radius="@dimen/dp_5" />--> | |||
<!-- <stroke--> | |||
<!-- android:width="1dp"--> | |||
<!-- android:color="@color/common_accent_color" />--> | |||
<!--</shape>--> | |||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |||
<item | |||
android:top="-2dp" | |||
android:right="-2dp" | |||
android:left="-2dp"> | |||
<shape> | |||
<solid android:color="@color/transparent"/> | |||
<stroke | |||
android:width="1dp" | |||
android:color="@color/common_accent_color"/> | |||
</shape> | |||
</item> | |||
</layer-list> |
@@ -0,0 +1,27 @@ | |||
<!--<?xml version="1.0" encoding="utf-8"?>--> | |||
<!--<shape xmlns:android="http://schemas.android.com/apk/res/android"--> | |||
<!-- android:shape="rectangle">--> | |||
<!-- <solid android:color="@color/white" />--> | |||
<!-- <!– 大小 –>--> | |||
<!-- <size--> | |||
<!-- android:width="@dimen/dp_40"--> | |||
<!-- android:height="@dimen/dp_40" /><!– 宽度和高度 –>--> | |||
<!-- <corners android:radius="@dimen/dp_5" />--> | |||
<!-- <stroke--> | |||
<!-- android:width="1dp"--> | |||
<!-- android:color="#AAAAAA" />--> | |||
<!--</shape>--> | |||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |||
<item | |||
android:top="-2dp" | |||
android:right="-2dp" | |||
android:left="-2dp"> | |||
<shape> | |||
<solid android:color="@color/transparent"/> | |||
<stroke | |||
android:width="1dp" | |||
android:color="#AAAAAA"/> | |||
</shape> | |||
</item> | |||
</layer-list> |
@@ -0,0 +1,75 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
style="@style/MatchMatch.Vertical" | |||
android:background="@color/background_color"> | |||
<com.hjq.bar.TitleBar | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:background="@color/transparent" | |||
app:leftIcon="@mipmap/back_black" | |||
app:lineVisible="false" | |||
app:title="" | |||
app:titleColor="@color/black" /> | |||
<androidx.core.widget.NestedScrollView | |||
style="@style/MatchWrap"> | |||
<LinearLayout style="@style/MatchWrap.Vertical" | |||
android:paddingVertical="@dimen/dp_50" | |||
android:paddingHorizontal="@dimen/dp_20"> | |||
<TextView | |||
style="@style/WrapWrap" | |||
android:text="忘记密码" | |||
android:paddingHorizontal="@dimen/dp_20" | |||
android:textColor="@color/color_333333" | |||
android:textSize="@dimen/sp_18" | |||
android:textStyle="bold"/> | |||
<TextView | |||
style="@style/WrapWrap" | |||
android:text="请输入手机号" | |||
android:textSize="@dimen/sp_13" | |||
android:textColor="@color/color_666666" | |||
android:paddingHorizontal="@dimen/dp_20" | |||
android:paddingVertical="@dimen/dp_15"/> | |||
<LinearLayout | |||
android:layout_width="match_parent" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_marginTop="@dimen/dp_35" | |||
android:background="@drawable/edit_bg" | |||
android:gravity="center_vertical" | |||
android:orientation="horizontal" | |||
android:paddingHorizontal="@dimen/dp_15"> | |||
<ImageView | |||
android:layout_width="13dp" | |||
android:layout_height="@dimen/dp_20" | |||
android:src="@mipmap/phone" /> | |||
<com.hjq.widget.view.ClearEditText | |||
android:id="@+id/et_login_phone" | |||
style="@style/EditTextStyle" | |||
android:layout_width="match_parent" | |||
android:layout_height="@dimen/dp_40" | |||
android:background="@null" | |||
android:hint="@string/common_phone_input_hint" | |||
android:inputType="phone" | |||
android:textColorHint="#B3B3B3" | |||
android:textColor="@color/color_333333" | |||
app:regexType="mobile" /> | |||
</LinearLayout> | |||
<Button | |||
android:id="@+id/btnConfirm" | |||
style="@style/BtnShortStyle" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_gravity="center" | |||
android:layout_marginTop="@dimen/dp_30" | |||
android:text="验证手机号" | |||
android:textSize="@dimen/sp_15" /> | |||
</LinearLayout> | |||
</androidx.core.widget.NestedScrollView> | |||
</LinearLayout> |
@@ -0,0 +1,87 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
style="@style/MatchMatch.Vertical" | |||
android:background="@color/background_color"> | |||
<com.hjq.bar.TitleBar | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:background="@color/transparent" | |||
app:leftIcon="@mipmap/back_black" | |||
app:lineVisible="false" | |||
app:title="" | |||
app:titleColor="@color/black" /> | |||
<androidx.core.widget.NestedScrollView | |||
style="@style/MatchWrap"> | |||
<LinearLayout style="@style/MatchWrap.Vertical" | |||
android:paddingVertical="@dimen/dp_50" | |||
android:paddingHorizontal="@dimen/dp_20"> | |||
<TextView | |||
style="@style/WrapWrap" | |||
android:text="请输入验证码" | |||
android:paddingHorizontal="@dimen/dp_20" | |||
android:textColor="@color/color_333333" | |||
android:textSize="@dimen/sp_18" | |||
android:textStyle="bold"/> | |||
<TextView | |||
android:id="@+id/tvPhone" | |||
style="@style/WrapWrap" | |||
android:text="验证码已发送至:xxx xxxx xxxx" | |||
android:textSize="@dimen/sp_13" | |||
android:textColor="@color/color_666666" | |||
android:paddingHorizontal="@dimen/dp_20" | |||
android:paddingVertical="@dimen/dp_15"/> | |||
<com.huntersun.vkyes.etcopencard.src.widget.vertfiycode.VerificationCodeView | |||
android:id="@+id/verPwd" | |||
style="@style/MatchWrap" | |||
android:layout_marginTop="@dimen/dp_20" | |||
android:layout_marginHorizontal="@dimen/dp_15" | |||
app:icv_et_bg_focus="@drawable/shape_icv_et_bg_focus" | |||
app:icv_et_bg_normal="@drawable/shape_icv_et_bg_normal" | |||
app:icv_et_divider_drawable="@drawable/shape_divider_identifying" | |||
app:icv_et_number="6" | |||
android:focusable="true" | |||
app:icv_et_pwd="false" | |||
app:icv_et_pwd_radius="3dp" | |||
app:icv_et_text_color="@color/common_accent_color" | |||
app:icv_et_text_size="@dimen/sp_20" | |||
app:icv_et_width="@dimen/dp_40" /> | |||
<LinearLayout | |||
style="@style/MatchWrap.Horizontal" | |||
android:paddingHorizontal="@dimen/dp_15" | |||
android:paddingVertical="@dimen/dp_15"> | |||
<TextView | |||
android:id="@+id/tvCountDownTime" | |||
style="@style/WrapWrap" | |||
android:text="00" | |||
android:textSize="@dimen/sp_10" | |||
android:textColor="@color/common_accent_color"/> | |||
<TextView | |||
style="@style/WrapWrap" | |||
android:text="秒后可重新发送验证码" | |||
android:textSize="@dimen/sp_10" | |||
android:layout_marginLeft="@dimen/dp_7" | |||
android:textColor="@color/color_666666"/> | |||
</LinearLayout> | |||
<Button | |||
android:id="@+id/btnConfirm" | |||
style="@style/BtnShortStyle" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_gravity="center" | |||
android:layout_marginTop="@dimen/dp_30" | |||
android:text="下一步" | |||
android:layout_marginHorizontal="@dimen/dp_12" | |||
android:textSize="@dimen/sp_15" /> | |||
</LinearLayout> | |||
</androidx.core.widget.NestedScrollView> | |||
</LinearLayout> |
@@ -0,0 +1,115 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
style="@style/MatchMatch.Vertical" | |||
android:background="@color/background_color"> | |||
<com.hjq.bar.TitleBar | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:background="@color/transparent" | |||
app:leftIcon="@mipmap/back_black" | |||
app:lineVisible="false" | |||
app:title="" | |||
app:titleColor="@color/black" /> | |||
<androidx.core.widget.NestedScrollView | |||
style="@style/MatchWrap"> | |||
<LinearLayout style="@style/MatchWrap.Vertical" | |||
android:paddingVertical="@dimen/dp_50" | |||
android:paddingHorizontal="@dimen/dp_20"> | |||
<TextView | |||
style="@style/WrapWrap" | |||
android:text="设置新的密码" | |||
android:paddingHorizontal="@dimen/dp_20" | |||
android:textColor="@color/color_333333" | |||
android:textSize="@dimen/sp_18" | |||
android:textStyle="bold"/> | |||
<TextView | |||
style="@style/WrapWrap" | |||
android:text="重置之前的密码,设置新密码" | |||
android:textSize="@dimen/sp_13" | |||
android:textColor="@color/color_666666" | |||
android:paddingHorizontal="@dimen/dp_20" | |||
android:paddingVertical="@dimen/dp_15"/> | |||
<LinearLayout | |||
android:layout_width="match_parent" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_marginTop="@dimen/dp_35" | |||
android:background="@drawable/edit_bg" | |||
android:gravity="center_vertical" | |||
android:orientation="horizontal" | |||
android:paddingHorizontal="@dimen/dp_15"> | |||
<ImageView | |||
android:layout_width="13dp" | |||
android:layout_height="@dimen/dp_20" | |||
android:src="@mipmap/password" /> | |||
<com.hjq.widget.view.PasswordEditText | |||
android:id="@+id/etPassword" | |||
style="@style/EditTextStyle" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:background="@null" | |||
android:hint="@string/common_password_input_error" | |||
android:imeOptions="actionDone" | |||
android:maxLength="20" | |||
android:singleLine="true" | |||
android:textColorHint="#B3B3B3" | |||
android:textColor="@color/color_333333"/> | |||
</LinearLayout> | |||
<LinearLayout | |||
android:layout_width="match_parent" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_marginTop="@dimen/dp_15" | |||
android:background="@drawable/edit_bg" | |||
android:gravity="center_vertical" | |||
android:orientation="horizontal" | |||
android:paddingHorizontal="@dimen/dp_15"> | |||
<ImageView | |||
android:layout_width="13dp" | |||
android:layout_height="@dimen/dp_20" | |||
android:src="@mipmap/password" /> | |||
<com.hjq.widget.view.PasswordEditText | |||
android:id="@+id/etAgainPassword" | |||
style="@style/EditTextStyle" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:background="@null" | |||
android:hint="请再次输入密码" | |||
android:imeOptions="actionDone" | |||
android:maxLength="20" | |||
android:singleLine="true" | |||
android:textColorHint="#B3B3B3" | |||
android:textColor="@color/color_333333"/> | |||
</LinearLayout> | |||
<TextView | |||
android:id="@+id/tvHintMsg" | |||
style="@style/MatchWrap" | |||
android:textSize="@dimen/sp_10" | |||
android:paddingHorizontal="@dimen/dp_15" | |||
android:paddingVertical="@dimen/dp_15" | |||
android:textColor="#FF5353" | |||
android:text="密码不少于8位,必须同时包含数字、大小写字母和特殊符号"/> | |||
<Button | |||
android:id="@+id/btnConfirm" | |||
style="@style/BtnShortStyle" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_gravity="center" | |||
android:text="确认更改" | |||
android:textSize="@dimen/sp_15" /> | |||
</LinearLayout> | |||
</androidx.core.widget.NestedScrollView> | |||
</LinearLayout> |
@@ -0,0 +1,24 @@ | |||
<?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"> | |||
<LinearLayout | |||
android:id="@+id/container_et" | |||
android:layout_width="wrap_content" | |||
android:layout_height="match_parent" | |||
android:layout_alignParentLeft="true" | |||
android:gravity="center_vertical" | |||
android:orientation="horizontal" | |||
android:showDividers="middle"> | |||
</LinearLayout> | |||
<com.huntersun.vkyes.etcopencard.src.widget.vertfiycode.PwdEditText | |||
android:id="@+id/et" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:background="@android:color/transparent" | |||
android:inputType="number" /> | |||
</RelativeLayout> |
@@ -52,7 +52,7 @@ | |||
<LinearLayout | |||
android:layout_width="match_parent" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_marginHorizontal="@dimen/dp_40" | |||
android:layout_marginHorizontal="@dimen/dp_20" | |||
android:layout_marginTop="@dimen/dp_10" | |||
android:background="@drawable/edit_bg" | |||
android:gravity="center_vertical" | |||
@@ -72,7 +72,6 @@ | |||
android:background="@null" | |||
android:hint="@string/common_phone_input_hint" | |||
android:inputType="textVisiblePassword" | |||
android:text="15764350434" | |||
app:regexType="mobile" /> | |||
</LinearLayout> | |||
@@ -80,7 +79,7 @@ | |||
<LinearLayout | |||
android:layout_width="match_parent" | |||
android:layout_height="@dimen/dp_40" | |||
android:layout_marginHorizontal="@dimen/dp_40" | |||
android:layout_marginHorizontal="@dimen/dp_20" | |||
android:layout_marginTop="@dimen/dp_20" | |||
android:background="@drawable/edit_bg" | |||
android:gravity="center_vertical" | |||
@@ -102,10 +101,22 @@ | |||
android:imeOptions="actionDone" | |||
android:maxLength="20" | |||
android:singleLine="true" | |||
android:text="6517@Qwer" /> | |||
/> | |||
</LinearLayout> | |||
<androidx.appcompat.widget.AppCompatTextView | |||
android:id="@+id/tv_login_forget" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_gravity="end" | |||
android:foreground="?attr/selectableItemBackground" | |||
android:text="@string/login_forget" | |||
android:paddingTop="@dimen/dp_15" | |||
android:paddingRight="@dimen/dp_15" | |||
android:paddingLeft="@dimen/dp_15" | |||
android:paddingBottom="@dimen/dp_10" | |||
android:textColor="@color/common_accent_color" /> | |||
<LinearLayout | |||
android:id="@+id/layout_code" | |||
@@ -139,8 +150,6 @@ | |||
</LinearLayout> | |||
<LinearLayout | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
@@ -159,13 +168,13 @@ | |||
android:text="手机号登录" | |||
android:textColor="@color/common_accent_color" /> | |||
<androidx.appcompat.widget.AppCompatTextView | |||
android:id="@+id/tv_login_forget" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_gravity="end" | |||
android:text="@string/login_forget" | |||
android:textColor="@color/common_accent_color" /> | |||
<!-- <androidx.appcompat.widget.AppCompatTextView--> | |||
<!-- android:id="@+id/tv_login_forget"--> | |||
<!-- android:layout_width="wrap_content"--> | |||
<!-- android:layout_height="wrap_content"--> | |||
<!-- android:layout_gravity="end"--> | |||
<!-- android:text="@string/login_forget"--> | |||
<!-- android:textColor="@color/common_accent_color" />--> | |||
</LinearLayout> | |||
@@ -174,7 +183,7 @@ | |||
style="@style/ButtonStyle" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:layout_marginHorizontal="@dimen/dp_40" | |||
android:layout_marginHorizontal="@dimen/dp_20" | |||
android:layout_marginTop="@dimen/dp_30" | |||
android:text="@string/login_text" /> | |||
@@ -350,4 +350,26 @@ | |||
<!-- 圆角矩形宽高相等,取较宽高中大值--> | |||
<attr name="mv_isWidthHeightEqual" format="boolean" /> | |||
</declare-styleable> | |||
<!-- 自定义验证码输入框--> | |||
<declare-styleable name="VerificationCodeView"> | |||
<!--输入框的数量--> | |||
<attr name="icv_et_number" format="integer" /> | |||
<!--输入框的宽度--> | |||
<attr name="icv_et_width" format="dimension|reference" /> | |||
<!--输入框之间的分割线--> | |||
<attr name="icv_et_divider_drawable" format="reference" /> | |||
<!--输入框文字颜色--> | |||
<attr name="icv_et_text_color" format="color|reference" /> | |||
<!--输入框文字大小--> | |||
<attr name="icv_et_text_size" format="dimension|reference" /> | |||
<!--输入框获取焦点时边框--> | |||
<attr name="icv_et_bg_focus" format="reference" /> | |||
<!--输入框没有焦点时边框--> | |||
<attr name="icv_et_bg_normal" format="reference" /> | |||
<!--是否是密码模式--> | |||
<attr name="icv_et_pwd" format="boolean" /> | |||
<!--密码模式时,圆的半径--> | |||
<attr name="icv_et_pwd_radius" format="dimension|reference" /> | |||
</declare-styleable> | |||
</resources> |