diff --git a/app/src/main/assets/config.properties b/app/src/main/assets/config.properties index ae52e13..8624297 100644 --- a/app/src/main/assets/config.properties +++ b/app/src/main/assets/config.properties @@ -1,2 +1,4 @@ -#登陆表单密码长度 -password.length=5 \ No newline at end of file +#注册密码大于长度 +password.length=5 +#注册账号大于长度 +username.length=5 \ No newline at end of file diff --git a/app/src/main/java/com/community/pocket/data/LoginDataSource.java b/app/src/main/java/com/community/pocket/data/login/LoginDataSource.java similarity index 95% rename from app/src/main/java/com/community/pocket/data/LoginDataSource.java rename to app/src/main/java/com/community/pocket/data/login/LoginDataSource.java index dc9f48a..c9ac35b 100644 --- a/app/src/main/java/com/community/pocket/data/LoginDataSource.java +++ b/app/src/main/java/com/community/pocket/data/login/LoginDataSource.java @@ -1,4 +1,4 @@ -package com.community.pocket.data; +package com.community.pocket.data.login; import com.community.pocket.data.model.LoggedInUser; diff --git a/app/src/main/java/com/community/pocket/data/LoginRepository.java b/app/src/main/java/com/community/pocket/data/login/LoginRepository.java similarity index 97% rename from app/src/main/java/com/community/pocket/data/LoginRepository.java rename to app/src/main/java/com/community/pocket/data/login/LoginRepository.java index 645265e..cf62598 100644 --- a/app/src/main/java/com/community/pocket/data/LoginRepository.java +++ b/app/src/main/java/com/community/pocket/data/login/LoginRepository.java @@ -1,4 +1,4 @@ -package com.community.pocket.data; +package com.community.pocket.data.login; import com.community.pocket.data.model.LoggedInUser; diff --git a/app/src/main/java/com/community/pocket/data/Result.java b/app/src/main/java/com/community/pocket/data/login/Result.java similarity index 97% rename from app/src/main/java/com/community/pocket/data/Result.java rename to app/src/main/java/com/community/pocket/data/login/Result.java index 3b40e5d..1bea384 100644 --- a/app/src/main/java/com/community/pocket/data/Result.java +++ b/app/src/main/java/com/community/pocket/data/login/Result.java @@ -1,4 +1,4 @@ -package com.community.pocket.data; +package com.community.pocket.data.login; import org.jetbrains.annotations.NotNull; diff --git a/app/src/main/java/com/community/pocket/data/register/RegisterRequest.java b/app/src/main/java/com/community/pocket/data/register/RegisterRequest.java new file mode 100644 index 0000000..315a4f4 --- /dev/null +++ b/app/src/main/java/com/community/pocket/data/register/RegisterRequest.java @@ -0,0 +1,23 @@ +package com.community.pocket.data.register; + +import com.community.pocket.util.Valid; + +/** + * 该类请求注册接口完成注册操作 + */ +public class RegisterRequest { + private static volatile RegisterRequest instance; + + + public static RegisterRequest getInstance() { + if (instance == null) { + instance = new RegisterRequest(); + } + return instance; + } + + //TODO 接口请求逻辑 + public Valid register(String username, String password, String confirmPassword, String mobilePhone, String email) { + return Valid.ok; + } +} diff --git a/app/src/main/java/com/community/pocket/ui/login/LoginActivity.java b/app/src/main/java/com/community/pocket/ui/login/LoginActivity.java index b01d6ec..8c46c16 100644 --- a/app/src/main/java/com/community/pocket/ui/login/LoginActivity.java +++ b/app/src/main/java/com/community/pocket/ui/login/LoginActivity.java @@ -2,19 +2,18 @@ package com.community.pocket.ui.login; import android.app.Activity; import android.content.Intent; +import android.os.Build; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; -import android.view.KeyEvent; import android.view.View; -import android.view.inputmethod.EditorInfo; import android.widget.Button; import android.widget.EditText; import android.widget.ProgressBar; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.annotation.StringRes; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; @@ -70,7 +69,7 @@ public class LoginActivity extends BaseActivity { } loginButton.setEnabled(loginFormState.isDataValid()); if (loginFormState.getUsernameError() != null) { - usernameEditText.setError(getString(loginFormState.getUsernameError())); + usernameEditText.setError(getString(loginFormState.getUsernameError(), PropertiesUtil.getIntValue("username.length"))); } if (loginFormState.getPasswordError() != null) { passwordEditText.setError(getString(loginFormState.getPasswordError(), PropertiesUtil.getIntValue("password.length"))); @@ -126,7 +125,8 @@ public class LoginActivity extends BaseActivity { } //登录按钮触发登录请求操作 - @Event(value = R.id.back) + @RequiresApi(api = Build.VERSION_CODES.N) + @Event(value = R.id.login) private void login(View v) { //显示登录请求处理进度 loadingProgressBar.setVisibility(View.VISIBLE); @@ -139,17 +139,6 @@ public class LoginActivity extends BaseActivity { startActivity(new Intent(this, RegisterActivity.class)); } - //监听密码软键盘输入 - @Event(type = TextView.OnEditorActionListener.class, value = R.id.password) - private boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - //点击完成执行登陆操作 - if (actionId == EditorInfo.IME_ACTION_DONE) { - loginViewModel.login(usernameEditText.getText().toString(), - passwordEditText.getText().toString()); - } - //默认不执行任何操作 - return false; - } @Event(value = R.id.login_to_resetPwd) private void resetRwd(View v) { diff --git a/app/src/main/java/com/community/pocket/ui/login/LoginViewModel.java b/app/src/main/java/com/community/pocket/ui/login/LoginViewModel.java index 1964afc..bcf6d83 100644 --- a/app/src/main/java/com/community/pocket/ui/login/LoginViewModel.java +++ b/app/src/main/java/com/community/pocket/ui/login/LoginViewModel.java @@ -1,18 +1,17 @@ package com.community.pocket.ui.login; -import android.util.Patterns; - import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import com.community.pocket.R; -import com.community.pocket.data.LoginRepository; -import com.community.pocket.data.Result; +import com.community.pocket.data.login.LoginRepository; +import com.community.pocket.data.login.Result; import com.community.pocket.data.model.LoggedInUser; +import com.community.pocket.util.PropertiesUtil; /** - * 登陆表单数据 + * 管理 登陆UI 相关数据 */ public class LoginViewModel extends ViewModel { @@ -62,19 +61,12 @@ public class LoginViewModel extends ViewModel { // A placeholder username validation check //用户名校验 private boolean isUserNameValid(String username) { - if (username == null) { - return false; - } - if (username.contains("@")) { - return Patterns.EMAIL_ADDRESS.matcher(username).matches(); - } else { - return !username.trim().isEmpty(); - } + 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() > 5; + return password != null && password.trim().length() > PropertiesUtil.getIntValue("password.length"); } } diff --git a/app/src/main/java/com/community/pocket/ui/login/LoginViewModelFactory.java b/app/src/main/java/com/community/pocket/ui/login/LoginViewModelFactory.java index 0f68c5f..5da08de 100644 --- a/app/src/main/java/com/community/pocket/ui/login/LoginViewModelFactory.java +++ b/app/src/main/java/com/community/pocket/ui/login/LoginViewModelFactory.java @@ -4,8 +4,8 @@ import androidx.annotation.NonNull; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; -import com.community.pocket.data.LoginDataSource; -import com.community.pocket.data.LoginRepository; +import com.community.pocket.data.login.LoginDataSource; +import com.community.pocket.data.login.LoginRepository; /** * ViewModel provider factory to instantiate LoginViewModel. diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/notifications/NotificationsFragment.java b/app/src/main/java/com/community/pocket/ui/main/ui/garbage/GarbageFragment.java similarity index 70% rename from app/src/main/java/com/community/pocket/ui/main/ui/notifications/NotificationsFragment.java rename to app/src/main/java/com/community/pocket/ui/main/ui/garbage/GarbageFragment.java index a90fab8..e169225 100644 --- a/app/src/main/java/com/community/pocket/ui/main/ui/notifications/NotificationsFragment.java +++ b/app/src/main/java/com/community/pocket/ui/main/ui/garbage/GarbageFragment.java @@ -1,4 +1,4 @@ -package com.community.pocket.ui.main.ui.notifications; +package com.community.pocket.ui.main.ui.garbage; import com.community.pocket.R; import com.community.pocket.ui.main.TestMainFragment; @@ -7,7 +7,7 @@ import org.xutils.view.annotation.ContentView; @ContentView(R.layout.fragment_notifications) -public class NotificationsFragment extends TestMainFragment { +public class GarbageFragment extends TestMainFragment { @Override protected int viewId() { diff --git a/app/src/main/java/com/community/pocket/ui/main/ui/notifications/NotificationsViewModel.java b/app/src/main/java/com/community/pocket/ui/main/ui/garbage/GarbageViewModel.java similarity index 68% rename from app/src/main/java/com/community/pocket/ui/main/ui/notifications/NotificationsViewModel.java rename to app/src/main/java/com/community/pocket/ui/main/ui/garbage/GarbageViewModel.java index c0c8023..5baa1d5 100644 --- a/app/src/main/java/com/community/pocket/ui/main/ui/notifications/NotificationsViewModel.java +++ b/app/src/main/java/com/community/pocket/ui/main/ui/garbage/GarbageViewModel.java @@ -1,14 +1,14 @@ -package com.community.pocket.ui.main.ui.notifications; +package com.community.pocket.ui.main.ui.garbage; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; -public class NotificationsViewModel extends ViewModel { +public class GarbageViewModel extends ViewModel { private MutableLiveData mText; - public NotificationsViewModel() { + public GarbageViewModel() { mText = new MutableLiveData<>(); mText.setValue("This is notifications fragment"); } diff --git a/app/src/main/java/com/community/pocket/ui/register/RegisterActivity.java b/app/src/main/java/com/community/pocket/ui/register/RegisterActivity.java index dcbf79e..0e5d56a 100644 --- a/app/src/main/java/com/community/pocket/ui/register/RegisterActivity.java +++ b/app/src/main/java/com/community/pocket/ui/register/RegisterActivity.java @@ -1,30 +1,148 @@ package com.community.pocket.ui.register; +import android.app.Activity; import android.content.Intent; import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; import android.view.View; +import android.widget.Button; +import android.widget.EditText; import android.widget.Toast; import androidx.annotation.Nullable; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; import com.community.pocket.R; import com.community.pocket.ui.BaseActivity; import com.community.pocket.ui.login.LoginActivity; +import com.community.pocket.util.PropertiesUtil; import org.xutils.view.annotation.ContentView; import org.xutils.view.annotation.Event; +import org.xutils.view.annotation.ViewInject; +/** + * 注册界面 + */ @ContentView(R.layout.activity_register) public class RegisterActivity extends BaseActivity { + + private RegisterViewModel registerViewModel; + + //用户名 + @ViewInject(R.id.username) + private EditText username; + + //密码 + @ViewInject(R.id.password) + private EditText password; + + //确认密码 + @ViewInject(R.id.confirmPassword) + private EditText confirmPassword; + + //手机号 + @ViewInject(R.id.phone) + private EditText mobiePhone; + + //邮箱 + @ViewInject(R.id.email) + private EditText email; + + //注册按钮 + @ViewInject(R.id.register) + private Button registerButton; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + registerViewModel = new ViewModelProvider(this, new RegisterViewModelFactory()).get(RegisterViewModel.class); + //监听注册表单校验状态 + registerViewModel.getRegisterFormState().observe(this, new Observer() { + @Override + public void onChanged(RegisterFormState registerFormState) { + if (registerFormState == null) { + return; + } + registerButton.setEnabled(registerFormState.isDataValid()); + if (registerFormState.getUsernameError() != null) { + username.setError(getString(registerFormState.getUsernameError(), PropertiesUtil.getIntValue("username.length"))); + } + if (registerFormState.getPasswordError() != null) { + password.setError(getString(registerFormState.getPasswordError(), PropertiesUtil.getIntValue("password.length"))); + } + if (registerFormState.getConfirmPasswordError() != null) { + if (registerFormState.getConfirmPasswordError() == R.string.invalid_password) { + confirmPassword.setError(getString(registerFormState.getConfirmPasswordError(), PropertiesUtil.getIntValue("password.length"))); + } else { + confirmPassword.setError(getString(registerFormState.getConfirmPasswordError())); + } + } + if (registerFormState.getPhoneError() != null) { + mobiePhone.setError(getString(registerFormState.getPhoneError())); + } + if (registerFormState.getEmailError() != null) { + email.setError(getString(registerFormState.getEmailError())); + } + } + }); + + TextWatcher afterTextChangedListener = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // ignore + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + // ignore + } + + @Override + public void afterTextChanged(Editable s) { + registerViewModel.registerDataChanged(username.getText().toString(), + password.getText().toString(), confirmPassword.getText().toString(), mobiePhone.getText().toString(), email.getText().toString()); + } + }; + + username.addTextChangedListener(afterTextChangedListener); + password.addTextChangedListener(afterTextChangedListener); + confirmPassword.addTextChangedListener(afterTextChangedListener); + mobiePhone.addTextChangedListener(afterTextChangedListener); + email.addTextChangedListener(afterTextChangedListener); + + //监听注册请求结果 + registerViewModel.getRegisterResult().observe(this, new Observer() { + @Override + public void onChanged(RegisterResult registerResult) { + if (registerResult == null) { + return; + } + + if (registerResult.getError() != null) { + Toast.makeText(getApplicationContext(), R.string.register_fail, Toast.LENGTH_SHORT).show(); + } + if (registerResult.getSuccess() != null) { + Toast.makeText(getApplicationContext(), R.string.register_ok, Toast.LENGTH_SHORT).show(); + } + + setResult(Activity.RESULT_OK); + + startActivity(new Intent(getApplicationContext(), LoginActivity.class)); + //Complete and destroy login activity once successful + finish(); + } + }); + } @Event(value = R.id.register) private void register(View v) { - Toast.makeText(this, getString(R.string.action_register), Toast.LENGTH_SHORT).show(); + registerViewModel.register(username.getText().toString(), password.getText().toString(), confirmPassword.getText().toString(), mobiePhone.getText().toString(), email.getText().toString()); } @Event(value = R.id.back) diff --git a/app/src/main/java/com/community/pocket/ui/register/RegisterFormState.java b/app/src/main/java/com/community/pocket/ui/register/RegisterFormState.java new file mode 100644 index 0000000..5a95eb3 --- /dev/null +++ b/app/src/main/java/com/community/pocket/ui/register/RegisterFormState.java @@ -0,0 +1,69 @@ +package com.community.pocket.ui.register; + +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; + +/** + * 注册表单数据校验 + */ +class RegisterFormState { + @Nullable + @StringRes + private Integer usernameError; + @Nullable + @StringRes + private Integer passwordError; + @Nullable + @StringRes + private Integer confirmPasswordError; + @Nullable + @StringRes + private Integer phoneError; + @Nullable + private Integer emailError; + + + private boolean isDataValid; + + + RegisterFormState(@Nullable Integer usernameError, @Nullable Integer passwordError, @Nullable Integer confirmPasswordError, @Nullable Integer phoneError, @Nullable Integer emailError) { + this.usernameError = usernameError; + this.passwordError = passwordError; + this.confirmPasswordError = confirmPasswordError; + this.phoneError = phoneError; + this.emailError = emailError; + } + + RegisterFormState(boolean isDataValid) { + this.isDataValid = isDataValid; + } + + @Nullable + Integer getUsernameError() { + return usernameError; + } + + @Nullable + Integer getPasswordError() { + return passwordError; + } + + @Nullable + Integer getConfirmPasswordError() { + return confirmPasswordError; + } + + @Nullable + Integer getPhoneError() { + return phoneError; + } + + @Nullable + Integer getEmailError() { + return emailError; + } + + boolean isDataValid() { + return isDataValid; + } +} diff --git a/app/src/main/java/com/community/pocket/ui/register/RegisterResult.java b/app/src/main/java/com/community/pocket/ui/register/RegisterResult.java new file mode 100644 index 0000000..6b7b195 --- /dev/null +++ b/app/src/main/java/com/community/pocket/ui/register/RegisterResult.java @@ -0,0 +1,33 @@ +package com.community.pocket.ui.register; + +import androidx.annotation.Nullable; + +/** + * 注册结果 + */ +class RegisterResult { + @Nullable + private Integer success; + @Nullable + private Integer error; + + @Nullable + Integer getSuccess() { + return success; + } + + RegisterResult setSuccess(@Nullable Integer success) { + this.success = success; + return this; + } + + @Nullable + Integer getError() { + return error; + } + + RegisterResult setError(@Nullable Integer error) { + this.error = error; + return this; + } +} diff --git a/app/src/main/java/com/community/pocket/ui/register/RegisterViewModel.java b/app/src/main/java/com/community/pocket/ui/register/RegisterViewModel.java new file mode 100644 index 0000000..f8a2798 --- /dev/null +++ b/app/src/main/java/com/community/pocket/ui/register/RegisterViewModel.java @@ -0,0 +1,86 @@ +package com.community.pocket.ui.register; + +import android.util.Patterns; + +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.ViewModel; + +import com.community.pocket.R; +import com.community.pocket.data.register.RegisterRequest; +import com.community.pocket.util.PropertiesUtil; +import com.community.pocket.util.Valid; + +import java.util.regex.Pattern; + +/** + * 管理注册UI相关数据 + */ +class RegisterViewModel extends ViewModel { + + //注册表单校验信息 + private MutableLiveData registerFormState = new MutableLiveData<>(); + //注册结果 + private MutableLiveData registerResult = new MutableLiveData<>(); + + //注册请求 + private RegisterRequest registerRequest; + + RegisterViewModel(RegisterRequest registerRequest) { + this.registerRequest = registerRequest; + } + + MutableLiveData getRegisterFormState() { + return registerFormState; + } + + MutableLiveData getRegisterResult() { + return registerResult; + } + + //注册 + void register(String username, String password, String confirmPassword, String mobilePhone, String email) { + Valid valid = registerRequest.register(username, password, confirmPassword, mobilePhone, email); + if (Valid.ok == valid) { + registerResult.setValue(new RegisterResult().setSuccess(R.string.register_ok)); + } else { + registerResult.setValue(new RegisterResult().setError(R.string.register_fail)); + } + } + + //监听注册表单数据变化触发数据校验 + void registerDataChanged(String username, String password, String confirmPassword, String mobilePhone, String email) { + if (!usernamevalid(username)) { + registerFormState.setValue(new RegisterFormState(R.string.invalid_username, null, null, null, null)); + } else if (!passwordvalid(password)) { + registerFormState.setValue(new RegisterFormState(null, R.string.invalid_password, null, null, null)); + } else if (!passwordvalid(confirmPassword)) { + registerFormState.setValue(new RegisterFormState(null, null, R.string.invalid_password, null, null)); + } else if (!confirmPassword.equals(password)) { + registerFormState.setValue(new RegisterFormState(null, null, R.string.invalid_confirm_password, null, null)); + } else if (!mobilePhoneValid(mobilePhone)) { + registerFormState.setValue(new RegisterFormState(null, null, null, R.string.invalid_mobiephone, null)); + } else if (!emailValid(email)) { + registerFormState.setValue(new RegisterFormState(null, null, null, null, R.string.invalid_email)); + } else { + 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"); + } + + +} diff --git a/app/src/main/java/com/community/pocket/ui/register/RegisterViewModelFactory.java b/app/src/main/java/com/community/pocket/ui/register/RegisterViewModelFactory.java new file mode 100644 index 0000000..abd02d3 --- /dev/null +++ b/app/src/main/java/com/community/pocket/ui/register/RegisterViewModelFactory.java @@ -0,0 +1,20 @@ +package com.community.pocket.ui.register; + +import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import com.community.pocket.data.register.RegisterRequest; + +public class RegisterViewModelFactory implements ViewModelProvider.Factory { + @NonNull + @Override + @SuppressWarnings("unchecked") + public T create(@NonNull Class modelClass) { + if (modelClass.isAssignableFrom(RegisterViewModel.class)) { + return (T) new RegisterViewModel(RegisterRequest.getInstance()); + } else { + throw new IllegalArgumentException("Unknown ViewModel class"); + } + } +} diff --git a/app/src/main/java/com/community/pocket/util/Valid.java b/app/src/main/java/com/community/pocket/util/Valid.java new file mode 100644 index 0000000..1e09235 --- /dev/null +++ b/app/src/main/java/com/community/pocket/util/Valid.java @@ -0,0 +1,9 @@ +package com.community.pocket.util; + +public enum Valid { + empty_err, + password_err, + password_diff_err, + ok, + fail +} diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 540d2c4..08d6f05 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -46,7 +46,6 @@ android:autofillHints="@string/AUTOFILL_HINT_PASSWORD" android:hint="@string/prompt_password" android:imeActionLabel="@string/action_sign_in_short" - android:imeOptions="actionDone" android:inputType="textPassword" android:selectAllOnFocus="true" app:layout_constraintEnd_toEndOf="parent" @@ -71,7 +70,7 @@ app:layout_constraintTop_toBottomOf="@id/loading">