增加重置密码UI表单校验、请求逻辑

0515
panqihua 5 years ago
parent 9faf67b2dc
commit db963809e2
  1. 1
      app/.gitignore
  2. BIN
      app/my.key
  3. 2
      app/src/main/java/com/community/pocket/data/register/RegisterRequest.java
  4. 51
      app/src/main/java/com/community/pocket/data/resetpwd/ResetPwdRequest.java
  5. 2
      app/src/main/java/com/community/pocket/ui/login/LoginActivity.java
  6. 18
      app/src/main/java/com/community/pocket/ui/login/LoginViewModel.java
  7. 6
      app/src/main/java/com/community/pocket/ui/register/RegisterActivity.java
  8. 31
      app/src/main/java/com/community/pocket/ui/register/RegisterViewModel.java
  9. 111
      app/src/main/java/com/community/pocket/ui/resetpwd/ResetPwdFormState.java
  10. 33
      app/src/main/java/com/community/pocket/ui/resetpwd/ResetPwdResult.java
  11. 105
      app/src/main/java/com/community/pocket/ui/resetpwd/ResetPwdStep1.java
  12. 115
      app/src/main/java/com/community/pocket/ui/resetpwd/ResetPwdStep2.java
  13. 96
      app/src/main/java/com/community/pocket/ui/resetpwd/ResetPwdStep3.java
  14. 148
      app/src/main/java/com/community/pocket/ui/resetpwd/ResetPwdViewModel.java
  15. 20
      app/src/main/java/com/community/pocket/ui/resetpwd/ResetPwdViewModelFactory.java
  16. 9
      app/src/main/java/com/community/pocket/util/Param.java
  17. 20
      app/src/main/java/com/community/pocket/util/Result.java
  18. 46
      app/src/main/java/com/community/pocket/util/ValidUtil.java
  19. 1
      app/src/main/res/layout/activity_register.xml
  20. 6
      app/src/main/res/layout/resetpwd/layout/step1.xml
  21. 28
      app/src/main/res/layout/resetpwd/layout/step2.xml
  22. 6
      app/src/main/res/layout/resetpwd/layout/step3.xml
  23. 11
      app/src/main/res/values-en-rUS/strings.xml
  24. 11
      app/src/main/res/values-zh-rCN/strings.xml
  25. 11
      app/src/main/res/values/strings.xml

1
app/.gitignore vendored

@ -1 +1,2 @@
/build /build
/release/

Binary file not shown.

@ -8,6 +8,8 @@ import com.community.pocket.util.Valid;
public class RegisterRequest { public class RegisterRequest {
private static volatile RegisterRequest instance; private static volatile RegisterRequest instance;
private RegisterRequest() {
}
public static RegisterRequest getInstance() { public static RegisterRequest getInstance() {
if (instance == null) { if (instance == null) {

@ -0,0 +1,51 @@
package com.community.pocket.data.resetpwd;
import com.community.pocket.util.Result;
import com.community.pocket.util.Valid;
/**
* 重置密码请求
* TODO 接口请求逻辑完善
*/
public class ResetPwdRequest {
private static volatile ResetPwdRequest instance;
private ResetPwdRequest() {
}
public static ResetPwdRequest getInstance() {
if (instance == null) {
instance = new ResetPwdRequest();
}
return instance;
}
/**
* 检查用户邮箱
*/
public Result<String> checkUser(String username, String email) {
return new Result<>(Valid.ok, null);
}
/**
* 发送验证码
*/
public Result<String> sendCode(String username, String email) {
return new Result<>(Valid.ok, null);
}
/**
* 检查验证码
*/
public Result<String> checkCode(String username, String email, String code) {
return new Result<>(Valid.ok, null);
}
/**
* 重置密码
*/
public Result<String> resetPwd(String username, String password) {
return new Result<>(Valid.ok, null);
}
}

@ -47,7 +47,7 @@ public class LoginActivity extends BaseActivity {
private EditText passwordEditText; private EditText passwordEditText;
//登录按钮 //登录按钮
@ViewInject(R.id.back) @ViewInject(R.id.login)
private Button loginButton; private Button loginButton;
//进度条 //进度条

@ -8,7 +8,7 @@ import com.community.pocket.R;
import com.community.pocket.data.login.LoginRepository; import com.community.pocket.data.login.LoginRepository;
import com.community.pocket.data.login.Result; import com.community.pocket.data.login.Result;
import com.community.pocket.data.model.LoggedInUser; import com.community.pocket.data.model.LoggedInUser;
import com.community.pocket.util.PropertiesUtil; import com.community.pocket.util.ValidUtil;
/** /**
* 管理 登陆UI 相关数据 * 管理 登陆UI 相关数据
@ -49,24 +49,12 @@ public class LoginViewModel extends ViewModel {
//登陆表单数据变化触发数据校验 //登陆表单数据变化触发数据校验
void loginDataChanged(String username, String password) { void loginDataChanged(String username, String password) {
if (!isUserNameValid(username)) { if (!ValidUtil.usernamevalid(username)) {
loginFormState.setValue(new LoginFormState(R.string.invalid_username, null)); loginFormState.setValue(new LoginFormState(R.string.invalid_username, null));
} else if (!isPasswordValid(password)) { } else if (!ValidUtil.passwordvalid(password)) {
loginFormState.setValue(new LoginFormState(null, R.string.invalid_password)); loginFormState.setValue(new LoginFormState(null, R.string.invalid_password));
} else { } else {
loginFormState.setValue(new LoginFormState(true)); loginFormState.setValue(new LoginFormState(true));
} }
} }
// A placeholder username validation check
//用户名校验
private boolean isUserNameValid(String username) {
return username != null && username.trim().length() > PropertiesUtil.getIntValue("username.length");
}
// A placeholder password validation check
//密码校验
private boolean isPasswordValid(String password) {
return password != null && password.trim().length() > PropertiesUtil.getIntValue("password.length");
}
} }

@ -128,13 +128,13 @@ public class RegisterActivity extends BaseActivity {
} }
if (registerResult.getSuccess() != null) { if (registerResult.getSuccess() != null) {
Toast.makeText(getApplicationContext(), R.string.register_ok, Toast.LENGTH_SHORT).show(); Toast.makeText(getApplicationContext(), R.string.register_ok, Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
//Complete and destroy login activity once successful
finish();
} }
setResult(Activity.RESULT_OK); setResult(Activity.RESULT_OK);
startActivity(new Intent(getApplicationContext(), LoginActivity.class));
//Complete and destroy login activity once successful
finish();
} }
}); });

@ -1,16 +1,12 @@
package com.community.pocket.ui.register; package com.community.pocket.ui.register;
import android.util.Patterns;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import com.community.pocket.R; import com.community.pocket.R;
import com.community.pocket.data.register.RegisterRequest; import com.community.pocket.data.register.RegisterRequest;
import com.community.pocket.util.PropertiesUtil;
import com.community.pocket.util.Valid; import com.community.pocket.util.Valid;
import com.community.pocket.util.ValidUtil;
import java.util.regex.Pattern;
/** /**
* 管理注册UI相关数据 * 管理注册UI相关数据
@ -49,38 +45,23 @@ class RegisterViewModel extends ViewModel {
//监听注册表单数据变化触发数据校验 //监听注册表单数据变化触发数据校验
void registerDataChanged(String username, String password, String confirmPassword, String mobilePhone, String email) { void registerDataChanged(String username, String password, String confirmPassword, String mobilePhone, String email) {
if (!usernamevalid(username)) { if (!ValidUtil.usernamevalid(username)) {
registerFormState.setValue(new RegisterFormState(R.string.invalid_username, null, null, null, null)); registerFormState.setValue(new RegisterFormState(R.string.invalid_username, null, null, null, null));
} else if (!passwordvalid(password)) { } else if (!ValidUtil.passwordvalid(password)) {
registerFormState.setValue(new RegisterFormState(null, R.string.invalid_password, null, null, null)); registerFormState.setValue(new RegisterFormState(null, R.string.invalid_password, null, null, null));
} else if (!passwordvalid(confirmPassword)) { } else if (!ValidUtil.passwordvalid(confirmPassword)) {
registerFormState.setValue(new RegisterFormState(null, null, R.string.invalid_password, null, null)); registerFormState.setValue(new RegisterFormState(null, null, R.string.invalid_password, null, null));
} else if (!confirmPassword.equals(password)) { } else if (!confirmPassword.equals(password)) {
registerFormState.setValue(new RegisterFormState(null, null, R.string.invalid_confirm_password, null, null)); registerFormState.setValue(new RegisterFormState(null, null, R.string.invalid_confirm_password, null, null));
} else if (!mobilePhoneValid(mobilePhone)) { } else if (!ValidUtil.mobilePhoneValid(mobilePhone)) {
registerFormState.setValue(new RegisterFormState(null, null, null, R.string.invalid_mobiephone, null)); registerFormState.setValue(new RegisterFormState(null, null, null, R.string.invalid_mobiephone, null));
} else if (!emailValid(email)) { } else if (!ValidUtil.emailValid(email)) {
registerFormState.setValue(new RegisterFormState(null, null, null, null, R.string.invalid_email)); registerFormState.setValue(new RegisterFormState(null, null, null, null, R.string.invalid_email));
} else { } else {
registerFormState.setValue(new RegisterFormState(true)); registerFormState.setValue(new RegisterFormState(true));
} }
} }
private boolean emailValid(String email) {
return Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
private boolean mobilePhoneValid(String mobilePhone) {
return Pattern.compile("^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$").matcher(mobilePhone).matches();
}
private boolean passwordvalid(String password) {
return password != null && password.trim().length() > PropertiesUtil.getIntValue("password.length");
}
private boolean usernamevalid(String username) {
return username != null && username.trim().length() > PropertiesUtil.getIntValue("username.length");
}
} }

@ -0,0 +1,111 @@
package com.community.pocket.ui.resetpwd;
import androidx.annotation.Nullable;
class ResetPwdFormState {
/**
* 重置密码第一步校验
*/
static class Step1 {
@Nullable
private Integer usernameError;
@Nullable
private Integer emailError;
private boolean isDataValid;
Step1(@Nullable Integer usernameError, @Nullable Integer emailError) {
this.usernameError = usernameError;
this.emailError = emailError;
}
Step1(boolean isDataValid) {
this.isDataValid = isDataValid;
}
@Nullable
Integer getUsernameError() {
return usernameError;
}
@Nullable
Integer getEmailError() {
return emailError;
}
boolean isDataValid() {
return isDataValid;
}
}
/**
* 重置密码第二步校验
*/
static class Step2 {
@Nullable
private Integer codeError;
//发送验证码剩余等待秒数
private Integer second;
private boolean isDataValid;
Step2(@Nullable Integer codeError) {
this.codeError = codeError;
}
Step2(@Nullable Integer codeError, Integer second) {
this.codeError = codeError;
this.second = second;
}
Step2(boolean isDataValid) {
this.isDataValid = isDataValid;
}
Integer getSecond() {
return second;
}
@Nullable
Integer getCodeError() {
return codeError;
}
boolean isDataValid() {
return isDataValid;
}
}
static class Step3 {
@Nullable
private Integer passwordError;
@Nullable
private Integer confirmPasswordError;
private boolean isDataValid;
Step3(@Nullable Integer passwordError, @Nullable Integer confirmPasswordError) {
this.passwordError = passwordError;
this.confirmPasswordError = confirmPasswordError;
}
Step3(boolean isDataValid) {
this.isDataValid = isDataValid;
}
@Nullable
Integer getPasswordError() {
return passwordError;
}
@Nullable
Integer getConfirmPasswordError() {
return confirmPasswordError;
}
boolean isDataValid() {
return isDataValid;
}
}
}

@ -0,0 +1,33 @@
package com.community.pocket.ui.resetpwd;
import androidx.annotation.Nullable;
/**
* 重置密码结果
*/
class ResetPwdResult {
@Nullable
private Integer success;
@Nullable
private Integer error;
@Nullable
Integer getSuccess() {
return success;
}
ResetPwdResult setSuccess(@Nullable Integer success) {
this.success = success;
return this;
}
@Nullable
Integer getError() {
return error;
}
ResetPwdResult setError(@Nullable Integer error) {
this.error = error;
return this;
}
}

@ -1,18 +1,32 @@
package com.community.pocket.ui.resetpwd; package com.community.pocket.ui.resetpwd;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.fragment.NavHostFragment;
import com.community.pocket.R; import com.community.pocket.R;
import com.community.pocket.ui.BaseFragment; import com.community.pocket.ui.BaseFragment;
import com.community.pocket.ui.login.LoginActivity; import com.community.pocket.ui.login.LoginActivity;
import com.community.pocket.util.Param;
import com.community.pocket.util.PropertiesUtil;
import org.xutils.view.annotation.ContentView; import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event; import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import java.util.Objects; import java.util.Objects;
@ -21,11 +35,98 @@ import java.util.Objects;
*/ */
@ContentView(R.layout.step1) @ContentView(R.layout.step1)
public class ResetPwdStep1 extends BaseFragment { public class ResetPwdStep1 extends BaseFragment {
@ViewInject(R.id.username)
private EditText username;
@ViewInject(R.id.email)
private EditText email;
private ResetPwdViewModel resetPwdViewModel;
@ViewInject(R.id.next)
private Button resetpwdButton;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
resetPwdViewModel = new ViewModelProvider(this, new ResetPwdViewModelFactory()).get(ResetPwdViewModel.class);
//监听表单校验状态
resetPwdViewModel.getResetPwdFormStep1().observe(getViewLifecycleOwner(), new Observer<ResetPwdFormState.Step1>() {
@Override
public void onChanged(ResetPwdFormState.Step1 step1) {
if (step1 == null) {
return;
}
resetpwdButton.setEnabled(step1.isDataValid());
if (step1.getUsernameError() != null) {
username.setError(getString(step1.getUsernameError(), PropertiesUtil.getIntValue("username.length")));
}
if (step1.getEmailError() != null) {
email.setError(getString(step1.getEmailError(), PropertiesUtil.getIntValue("password.length")));
}
}
});
//监听输入框文本
TextWatcher afterTextChangedListener = new 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 s) {
resetPwdViewModel.resetpwdStep1Changed(username.getText().toString(), email.getText().toString());
}
};
username.addTextChangedListener(afterTextChangedListener);
email.addTextChangedListener(afterTextChangedListener);
//监听重置密码第一步请求
resetPwdViewModel.getResetPwdResultStep1().observe(getViewLifecycleOwner(), new Observer<ResetPwdResult>() {
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onChanged(ResetPwdResult step1) {
if (step1 == null) {
return;
}
if (step1.getError() != null) {
Toast.makeText(getContext(), step1.getError(), Toast.LENGTH_LONG).show();
}
if (step1.getSuccess() != null) {
Toast.makeText(getContext(), step1.getSuccess(), Toast.LENGTH_LONG).show();
Bundle bundle = new Bundle();
bundle.putString(Param.username.name(), username.getText().toString());
bundle.putString(Param.email.name(), email.getText().toString());
NavHostFragment.findNavController(ResetPwdStep1.this)
.navigate(R.id.action_First2Fragment_to_Second2Fragment, bundle);
}
Objects.requireNonNull(getActivity()).setResult(Activity.RESULT_OK);
}
});
}
//进入下一步发送验证码 //进入下一步发送验证码
@Event(value = R.id.next) @Event(value = R.id.next)
private void onClick(View view) { private void onClick(View view) {
NavHostFragment.findNavController(ResetPwdStep1.this) resetPwdViewModel.checkUser(username.getText().toString(), email.getText().toString());
.navigate(R.id.action_First2Fragment_to_Second2Fragment);
} }
//返回登陆 //返回登陆

@ -1,15 +1,30 @@
package com.community.pocket.ui.resetpwd; package com.community.pocket.ui.resetpwd;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.fragment.NavHostFragment;
import com.community.pocket.R; import com.community.pocket.R;
import com.community.pocket.ui.BaseFragment; import com.community.pocket.ui.BaseFragment;
import com.community.pocket.util.Param;
import org.xutils.view.annotation.ContentView; import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event; import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import java.util.Objects;
/** /**
* 重置密码第二步发送验证码输入 * 重置密码第二步发送验证码输入
@ -17,6 +32,26 @@ import org.xutils.view.annotation.Event;
@ContentView(R.layout.step2) @ContentView(R.layout.step2)
public class ResetPwdStep2 extends BaseFragment { public class ResetPwdStep2 extends BaseFragment {
@ViewInject(R.id.username)
private EditText username;
@ViewInject(R.id.email)
private EditText email;
//验证码
@ViewInject(R.id.code)
private EditText code;
//发送验证码按钮
@ViewInject(R.id.sendcode)
private Button sendCode;
//下一步按钮
@ViewInject(R.id.next)
private Button next;
private ResetPwdViewModel resetPwdViewModel;
/** /**
* 返回第一步输入账号邮箱 * 返回第一步输入账号邮箱
*/ */
@ -26,13 +61,87 @@ public class ResetPwdStep2 extends BaseFragment {
.navigate(R.id.action_Second2Fragment_to_First2Fragment); .navigate(R.id.action_Second2Fragment_to_First2Fragment);
} }
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
username.setText(Objects.requireNonNull(getArguments()).getString(Param.username.name()));
email.setText(Objects.requireNonNull(getArguments()).getString(Param.email.name()));
resetPwdViewModel = new ViewModelProvider(this, new ResetPwdViewModelFactory()).get(ResetPwdViewModel.class);
//监控表单数据校验状态
resetPwdViewModel.getResetPwdFormStep2().observe(getViewLifecycleOwner(), new Observer<ResetPwdFormState.Step2>() {
@Override
public void onChanged(ResetPwdFormState.Step2 step2) {
if (step2 == null) {
return;
}
next.setEnabled(step2.isDataValid());
if (step2.getCodeError() != null) {
code.setError(getString(step2.getCodeError()));
}
}
});
//监听输入框文本
TextWatcher afterTextChangedListener = new 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 s) {
resetPwdViewModel.resetpwdStep2Changed(code.getText().toString());
}
};
code.addTextChangedListener(afterTextChangedListener);
resetPwdViewModel.getResetPwdResultStep2().observe(getViewLifecycleOwner(), new Observer<ResetPwdResult>() {
@Override
public void onChanged(ResetPwdResult resetPwdResult) {
if (resetPwdResult == null) {
return;
}
if (resetPwdResult.getSuccess() != null) {
Toast.makeText(getContext(), resetPwdResult.getSuccess(), Toast.LENGTH_LONG).show();
if (resetPwdResult.getSuccess() == R.string.resetpwd_step2_ok) {
code.setEnabled(true);
} else {
Bundle bundle = new Bundle();
bundle.putString(Param.username.name(), username.getText().toString());
NavHostFragment.findNavController(ResetPwdStep2.this)
.navigate(R.id.action_Second2Fragment_to_threeFragment, bundle);
}
}
if (resetPwdResult.getError() != null) {
Toast.makeText(getContext(), resetPwdResult.getError(), Toast.LENGTH_LONG).show();
if (resetPwdResult.getError() == R.string.resetpwd_step2_fail) {
code.setEnabled(false);
}
}
}
});
}
/** /**
* 进入下一步重置密码 * 进入下一步重置密码
*/ */
@Event(value = R.id.next) @Event(value = R.id.next)
private void next(View view) { private void next(View view) {
NavHostFragment.findNavController(ResetPwdStep2.this) resetPwdViewModel.checkCode(username.getText().toString(), email.getText().toString(), code.getText().toString());
.navigate(R.id.action_Second2Fragment_to_threeFragment);
} }
/** /**
@ -40,6 +149,6 @@ public class ResetPwdStep2 extends BaseFragment {
*/ */
@Event(value = R.id.sendcode) @Event(value = R.id.sendcode)
private void sendCode(View view) { private void sendCode(View view) {
Toast.makeText(getContext(), R.string.action_sendcode, Toast.LENGTH_SHORT).show(); resetPwdViewModel.sendCode(username.getText().toString(), email.getText().toString());
} }
} }

@ -2,17 +2,29 @@ package com.community.pocket.ui.resetpwd;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import com.community.pocket.R; import com.community.pocket.R;
import com.community.pocket.ui.BaseFragment; import com.community.pocket.ui.BaseFragment;
import com.community.pocket.ui.login.LoginActivity; import com.community.pocket.ui.login.LoginActivity;
import com.community.pocket.util.Param;
import com.community.pocket.util.PropertiesUtil;
import org.xutils.view.annotation.ContentView; import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event; import org.xutils.view.annotation.Event;
import org.xutils.view.annotation.ViewInject;
import java.util.Objects; import java.util.Objects;
@ -22,9 +34,91 @@ import java.util.Objects;
@ContentView(R.layout.step3) @ContentView(R.layout.step3)
public class ResetPwdStep3 extends BaseFragment { public class ResetPwdStep3 extends BaseFragment {
//密码
@ViewInject(R.id.password)
private EditText password;
//确认密码
@ViewInject(R.id.confirmPwd)
private EditText confirmPassword;
//重置密码按钮
@ViewInject(R.id.reset_pwd)
private Button resetpwdButton;
private ResetPwdViewModel resetPwdViewModel;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
resetPwdViewModel = new ViewModelProvider(this, new ResetPwdViewModelFactory()).get(ResetPwdViewModel.class);
//监听表单校验状态
resetPwdViewModel.getResetPwdFormStep3().observe(getViewLifecycleOwner(), new Observer<ResetPwdFormState.Step3>() {
@Override
public void onChanged(ResetPwdFormState.Step3 step3) {
if (step3 == null) {
return;
}
if (step3.getPasswordError() != null) {
password.setError(getString(step3.getPasswordError(), PropertiesUtil.getIntValue("password.length")));
}
if (step3.getConfirmPasswordError() != null) {
confirmPassword.setError(getString(step3.getConfirmPasswordError(), PropertiesUtil.getIntValue("password.length")));
}
resetpwdButton.setEnabled(step3.isDataValid());
}
});
TextWatcher textWatcher = new 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 s) {
resetPwdViewModel.resetpwdStep3Changed(password.getText().toString(), confirmPassword.getText().toString());
}
};
password.addTextChangedListener(textWatcher);
confirmPassword.addTextChangedListener(textWatcher);
resetPwdViewModel.getResetPwdResultStep3().observe(getViewLifecycleOwner(), new Observer<ResetPwdResult>() {
@Override
public void onChanged(ResetPwdResult resetPwdResult) {
if (resetPwdResult == null) {
return;
}
if (resetPwdResult.getSuccess() != null) {
Toast.makeText(getContext(), getString(R.string.resetpwd_step3_ok), Toast.LENGTH_LONG).show();
startActivity(new Intent(getContext(), LoginActivity.class));
}
if (resetPwdResult.getError() != null) {
Toast.makeText(getContext(), getString(R.string.resetpwd_step3_fail), Toast.LENGTH_LONG).show();
}
}
});
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Event(value = R.id.reset_pwd) @Event(value = R.id.reset_pwd)
private void resetPwd(View v) { private void resetPwd(View v) {
Toast.makeText(getContext(), R.string.action_reset_password, Toast.LENGTH_SHORT).show(); resetPwdViewModel.resetPwd(Objects.requireNonNull(getArguments()).getString(Param.username.name()), password.getText().toString());
} }
@RequiresApi(api = Build.VERSION_CODES.KITKAT) @RequiresApi(api = Build.VERSION_CODES.KITKAT)

@ -0,0 +1,148 @@
package com.community.pocket.ui.resetpwd;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.community.pocket.R;
import com.community.pocket.data.resetpwd.ResetPwdRequest;
import com.community.pocket.util.Result;
import com.community.pocket.util.Valid;
import com.community.pocket.util.ValidUtil;
/**
* 重置密码UI数据管理
*/
class ResetPwdViewModel extends ViewModel {
//重置密码第一步校验状态
private MutableLiveData<ResetPwdFormState.Step1> resetPwdFormStep1 = new MutableLiveData<>();
//重置密码第一步验证结果
private MutableLiveData<ResetPwdResult> resetPwdResultStep1 = new MutableLiveData<>();
//重置密码第二步校验状态
private MutableLiveData<ResetPwdFormState.Step2> resetPwdFormStep2 = new MutableLiveData<>();
//重置密码第二步发送验证码结果
private MutableLiveData<ResetPwdResult> resetPwdResultStep2 = new MutableLiveData<>();
//重置密码第三步校验状态
private MutableLiveData<ResetPwdFormState.Step3> resetPwdFormStep3 = new MutableLiveData<>();
//重置密码第三部重置结果
private MutableLiveData<ResetPwdResult> resetPwdResultStep3 = new MutableLiveData<>();
//重置密码请求
private ResetPwdRequest resetPwdRequest;
ResetPwdViewModel(ResetPwdRequest resetPwdRequest) {
this.resetPwdRequest = resetPwdRequest;
}
MutableLiveData<ResetPwdFormState.Step1> getResetPwdFormStep1() {
return resetPwdFormStep1;
}
MutableLiveData<ResetPwdResult> getResetPwdResultStep1() {
return resetPwdResultStep1;
}
MutableLiveData<ResetPwdFormState.Step2> getResetPwdFormStep2() {
return resetPwdFormStep2;
}
MutableLiveData<ResetPwdResult> getResetPwdResultStep2() {
return resetPwdResultStep2;
}
MutableLiveData<ResetPwdFormState.Step3> getResetPwdFormStep3() {
return resetPwdFormStep3;
}
MutableLiveData<ResetPwdResult> getResetPwdResultStep3() {
return resetPwdResultStep3;
}
//重置密码第一步
void checkUser(String username, String email) {
Result<String> result = resetPwdRequest.checkUser(username, email);
if (result.getValid() == Valid.ok) {
resetPwdResultStep1.setValue(new ResetPwdResult().setSuccess(R.string.resetpwd_step1_ok));
} else {
resetPwdResultStep1.setValue(new ResetPwdResult().setError(R.string.resetpwd_step1_fail));
}
}
//重置密码第二步
void sendCode(String username, String email) {
Result<String> result = resetPwdRequest.sendCode(username, email);
if (result.getValid() == Valid.ok) {
resetPwdResultStep2.setValue(new ResetPwdResult().setSuccess(R.string.resetpwd_step2_ok));
resetpwdStep2Changed();
} else {
resetPwdResultStep2.setValue(new ResetPwdResult().setError(R.string.resetpwd_step2_fail));
}
}
//重置密码第二步
void checkCode(String username, String email, String code) {
Result<String> result = resetPwdRequest.checkCode(username, email, code);
if (result.getValid() == Valid.ok) {
resetPwdResultStep2.setValue(new ResetPwdResult().setSuccess(R.string.resetpwd_step2_valid_ok));
} else {
resetPwdResultStep2.setValue(new ResetPwdResult().setError(R.string.resetpwd_step2_valid_fail));
}
}
//重置密码第三步
void resetPwd(String username, String password) {
Result<String> result = resetPwdRequest.resetPwd(username, password);
if (result.getValid() == Valid.ok) {
resetPwdResultStep3.setValue(new ResetPwdResult().setSuccess(R.string.resetpwd_step3_ok));
} else {
resetPwdResultStep3.setValue(new ResetPwdResult().setError(R.string.resetpwd_step3_fail));
}
}
//监听重置密码第一步表单触发校验
void resetpwdStep1Changed(String username, String email) {
if (!ValidUtil.usernamevalid(username)) {
resetPwdFormStep1.setValue(new ResetPwdFormState.Step1(R.string.invalid_username, null));
} else if (!ValidUtil.emailValid(email)) {
resetPwdFormStep1.setValue(new ResetPwdFormState.Step1(null, R.string.invalid_email));
} else {
resetPwdFormStep1.setValue(new ResetPwdFormState.Step1(true));
}
}
//TODO 异步更新验证码状态
private void resetpwdStep2Changed() {
// int second=60;
// while (second-->0) {
// try {
// TimeUnit.SECONDS.sleep(1);
// resetPwdFormStep2.setValue(new ResetPwdFormState.Step2(R.string.invalid_send_CAPTCHA,second));
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
//监听重置密码第二步表单触发校验
void resetpwdStep2Changed(String code) {
if (!ValidUtil.CAPTCHAValid(code)) {
resetPwdFormStep2.setValue(new ResetPwdFormState.Step2(R.string.invalid_CAPTCHA));
} else {
resetPwdFormStep2.setValue(new ResetPwdFormState.Step2(true));
}
}
//监听重置密码第三步表单触发校验
void resetpwdStep3Changed(String password, String confirmPassword) {
if (!ValidUtil.passwordvalid(password)) {
resetPwdFormStep3.setValue(new ResetPwdFormState.Step3(R.string.invalid_password, null));
} else if (!ValidUtil.passwordvalid(confirmPassword)) {
resetPwdFormStep3.setValue(new ResetPwdFormState.Step3(null, R.string.invalid_password));
} else if (!password.equals(confirmPassword)) {
resetPwdFormStep3.setValue(new ResetPwdFormState.Step3(null, R.string.invalid_confirm_password));
} else {
resetPwdFormStep3.setValue(new ResetPwdFormState.Step3(true));
}
}
}

@ -0,0 +1,20 @@
package com.community.pocket.ui.resetpwd;
import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;
import com.community.pocket.data.resetpwd.ResetPwdRequest;
public class ResetPwdViewModelFactory implements ViewModelProvider.Factory {
@NonNull
@Override
@SuppressWarnings("unchecked")
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (modelClass.isAssignableFrom(ResetPwdViewModel.class)) {
return (T) new ResetPwdViewModel(ResetPwdRequest.getInstance());
} else {
throw new IllegalArgumentException("Unknown ViewModel class");
}
}
}

@ -0,0 +1,9 @@
package com.community.pocket.util;
/**
* 参数传递Key
*/
public enum Param {
username,
email
}

@ -0,0 +1,20 @@
package com.community.pocket.util;
public class Result<T> {
private Valid valid;
private T body;
public Result(Valid valid, T body) {
this.valid = valid;
this.body = body;
}
public Valid getValid() {
return valid;
}
public T getBody() {
return body;
}
}

@ -0,0 +1,46 @@
package com.community.pocket.util;
import android.util.Patterns;
import java.util.regex.Pattern;
/**
* 表单校验工具类
*/
public class ValidUtil {
/**
* 校验邮箱
*/
public static boolean emailValid(String email) {
return Patterns.EMAIL_ADDRESS.matcher(email).matches();
}
/**
* 校验手机号
*/
public static boolean mobilePhoneValid(String mobilePhone) {
return Pattern.compile("^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$").matcher(mobilePhone).matches();
}
/**
* 校验密码
*/
public static boolean passwordvalid(String password) {
return password != null && password.trim().length() > PropertiesUtil.getIntValue("password.length");
}
/**
* 校验用户名
*/
public static boolean usernamevalid(String username) {
return username != null && username.trim().length() > PropertiesUtil.getIntValue("username.length");
}
/**
* 校验验证码
*/
public static boolean CAPTCHAValid(String code) {
return Pattern.compile("^\\d{6}$").matcher(code).matches();
}
}

@ -104,6 +104,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/size_50" android:layout_marginStart="@dimen/size_50"
android:enabled="false"
android:text="@string/action_register" android:text="@string/action_register"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

@ -10,9 +10,6 @@
android:id="@+id/username" android:id="@+id/username"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="24dp"
android:autofillHints="@string/AUTOFILL_HINT_USERNAME" android:autofillHints="@string/AUTOFILL_HINT_USERNAME"
android:hint="@string/prompt_user" android:hint="@string/prompt_user"
@ -26,10 +23,8 @@
android:id="@+id/email" android:id="@+id/email"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:autofillHints="@string/AUTOFILL_HINT_USERNAME" android:autofillHints="@string/AUTOFILL_HINT_USERNAME"
android:hint="@string/prompt_email" android:hint="@string/prompt_email"
android:inputType="text|textEmailAddress" android:inputType="text|textEmailAddress"
@ -52,6 +47,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/size_50" android:layout_marginStart="@dimen/size_50"
android:enabled="false"
android:text="@string/next" android:text="@string/next"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

@ -10,35 +10,44 @@
android:id="@+id/username" android:id="@+id/username"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="24dp"
android:autofillHints="@string/AUTOFILL_HINT_USERNAME" android:autofillHints="@string/AUTOFILL_HINT_USERNAME"
android:enabled="false" android:enabled="false"
android:hint="@string/prompt_user" android:hint="@string/prompt_user"
android:inputType="text"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
tools:ignore="TextFields" />
<EditText <EditText
android:id="@+id/email" android:id="@+id/email"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:autofillHints="@string/AUTOFILL_HINT_USERNAME" android:autofillHints="@string/AUTOFILL_HINT_USERNAME"
android:enabled="false" android:enabled="false"
android:hint="@string/prompt_email" android:hint="@string/prompt_email"
android:inputType="text|textEmailAddress"
android:selectAllOnFocus="true" android:selectAllOnFocus="true"
app:layout_constraintEnd_toStartOf="@id/sendcode" app:layout_constraintEnd_toStartOf="@id/sendcode"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/username" app:layout_constraintTop_toBottomOf="@+id/username"
tools:layout_constraintTop_toBottomOf="@id/username" /> tools:layout_constraintTop_toBottomOf="@id/username"
tools:ignore="TextFields" />
<EditText
android:id="@+id/code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ems="10"
android:enabled="false"
android:hint="@string/prompt_code"
android:importantForAutofill="no"
android:inputType="number"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/email" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="0dp" android:layout_width="0dp"
@ -46,13 +55,14 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/email"> app:layout_constraintTop_toBottomOf="@id/code">
<Button <Button
android:id="@+id/next" android:id="@+id/next"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/size_50" android:layout_marginStart="@dimen/size_50"
android:enabled="false"
android:text="@string/next" android:text="@string/next"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

@ -8,9 +8,6 @@
android:id="@+id/password" android:id="@+id/password"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="96dp"
android:layout_marginEnd="24dp"
android:autofillHints="@string/AUTOFILL_HINT_USERNAME" android:autofillHints="@string/AUTOFILL_HINT_USERNAME"
android:hint="@string/prompt_password" android:hint="@string/prompt_password"
@ -24,10 +21,8 @@
android:id="@+id/confirmPwd" android:id="@+id/confirmPwd"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:autofillHints="@string/AUTOFILL_HINT_USERNAME" android:autofillHints="@string/AUTOFILL_HINT_USERNAME"
android:hint="@string/prompt_confirm_password" android:hint="@string/prompt_confirm_password"
android:inputType="text|textPassword" android:inputType="text|textPassword"
@ -59,6 +54,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/size_50" android:layout_marginStart="@dimen/size_50"
android:enabled="false"
android:text="@string/action_reset_password" android:text="@string/action_reset_password"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

@ -96,4 +96,15 @@
<string name="invalid_email">Invalid mailbox</string> <string name="invalid_email">Invalid mailbox</string>
<string name="register_ok">register OK</string> <string name="register_ok">register OK</string>
<string name="register_fail">register fail</string> <string name="register_fail">register fail</string>
<string name="resetpwd_step1_fail">username or email error</string>
<string name="resetpwd_step1_ok">Check success</string>
<string name="prompt_code">please input code</string>
<string name="resetpwd_step2_ok">send code success</string>
<string name="resetpwd_step2_fail">send code error</string>
<string name="invalid_CAPTCHA">CAPTCHA Error</string>
<string name="resetpwd_step2_valid_ok">check success</string>
<string name="resetpwd_step2_valid_fail">check fail</string>
<string name="invalid_send_CAPTCHA">try again after %1d seconds</string>
<string name="resetpwd_step3_ok">reset password success</string>
<string name="resetpwd_step3_fail">reset password error</string>
</resources> </resources>

@ -96,4 +96,15 @@
<string name="register_ok">注册成功</string> <string name="register_ok">注册成功</string>
<string name="register_fail">注册失败</string> <string name="register_fail">注册失败</string>
<string name="invalid_username">用户名必须大于%1$s个字符</string> <string name="invalid_username">用户名必须大于%1$s个字符</string>
<string name="resetpwd_step1_fail">用户名或邮箱错误</string>
<string name="resetpwd_step1_ok">校验成功</string>
<string name="prompt_code">请输入验证码</string>
<string name="resetpwd_step2_ok">发送验证码成功</string>
<string name="resetpwd_step2_fail">发送验证码失败</string>
<string name="invalid_CAPTCHA">验证码不合法</string>
<string name="resetpwd_step2_valid_ok">验证码校验成功</string>
<string name="resetpwd_step2_valid_fail">验证码校验失败</string>
<string name="invalid_send_CAPTCHA">%1d秒后再试</string>
<string name="resetpwd_step3_ok">重置密码成功</string>
<string name="resetpwd_step3_fail">重置密码失败</string>
</resources> </resources>

@ -97,6 +97,17 @@
<string name="invalid_email">Invalid mailbox</string> <string name="invalid_email">Invalid mailbox</string>
<string name="register_ok">register OK</string> <string name="register_ok">register OK</string>
<string name="register_fail">register fail</string> <string name="register_fail">register fail</string>
<string name="resetpwd_step1_fail">username or email error</string>
<string name="resetpwd_step1_ok">Check success</string>
<string name="prompt_code">please input code</string>
<string name="resetpwd_step2_ok">send code success</string>
<string name="resetpwd_step2_fail">send code error</string>
<string name="invalid_CAPTCHA">CAPTCHA Error</string>
<string name="resetpwd_step2_valid_ok">check success</string>
<string name="resetpwd_step2_valid_fail">check fail</string>
<string name="invalid_send_CAPTCHA">try again after %1d seconds</string>
<string name="resetpwd_step3_ok">reset password success</string>
<string name="resetpwd_step3_fail">reset password error</string>
<!-- Strings used for fragments for navigation --> <!-- Strings used for fragments for navigation -->
<!-- Strings used for fragments for navigation --> <!-- Strings used for fragments for navigation -->

Loading…
Cancel
Save