“This is my 27th day of participating in the First Challenge 2022. For more details: First Challenge 2022

The last article demonstrated SQLite usage, and this article is a hands-on login

viewBinding

Use viewBinding to kill findViewById()

android {
...
buildFeatures {
    viewBinding true}}Copy the code

Login Activity

LoginActivity layout file, there is a FrameLayout, login and registration interface is Fragment


      
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/fragment_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Binding for the LoginActivity layout file

private ActivityLoginBinding mBinding;
Copy the code

Create the layout setContentView(mbinding.getroot ());

public class LoginActivity extends AppCompatActivity {

    private ActivityLoginBinding mBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = ActivityLoginBinding.inflate(getLayoutInflater());
        setContentView(mBinding.getRoot());
    
LoginFragment loginFragment = LoginFragment.newInstance();

     FragmentManager fm = getSupportFragmentManager();
     fm.beginTransaction()
        .add(R.id.fragment_content, loginFragment)
        .commit();

  }
Copy the code

Logon logic

public class LoginFragment extends Fragment {
    private FragmentLoginBinding mBinding;

    public static LoginFragment newInstance(a) {
        return new LoginFragment();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBinding = FragmentLoginBinding.inflate(inflater, container, false);
        return mBinding.getRoot();
    }
Copy the code

The registered click event requests the parent layout manager to replace the current page to execute the transaction

mBinding.btnRegister.setOnClickListener(v -> {
    RegisterFragment registerFragment = RegisterFragment.newInstance();
    getParentFragmentManager()
            .beginTransaction()
            //Fragment toggle left and right smooth animation
            .setCustomAnimations(
                    R.anim.slide_in_right,
                    R.anim.slide_out_left,
                    R.anim.slide_in_left,
                    R.anim.slide_out_right
            )
            .add(R.id.fragment_content, registerFragment)
            .addToBackStack(RegisterFragment.TAG)
            .commit();
});
Copy the code

Let’s assume it’s already registered

Then the login logic determines whether to enter the user name to verify that the password is correct

Administrator Account password

public static final String AdminUserName = "admin";
public static final String AdminUserPassWord = "123456";
Copy the code
/ / login
mBinding.btnLogin.setOnClickListener(v -> {
    if (checkContent()) {
    // Whether it is an administrator account
        if (userName.equals(Constant.AdminUserName)) {
            if (checkAdminPassWord()) {
               // The administrator password is correct}}else if (checkPassWord()) {
                // The user password is correct}}});Copy the code
** @return */ private Boolean checkContent() {userName = mBinding.etUsernameLayout.getEditText().getText().toString(); passWord = mBinding.etPasswordLayout.getEditText().getText().toString(); If (textutils.isempty (userName)) {showTosat(" userName cannot be empty "); return false; } if (textutils.isempty (userName)) {showTosat(" password cannot be empty "); return false; } return true; }Copy the code

Check whether you are an administrator

Checking the administrator password

private boolean checkAdminPassWord(a) {
    if (userName.equals(Constant.AdminUserName)) {
        if (passWord.equals(Constant.AdminUserPassWord)) {
            return true;
        } else {
            showTosat("Incorrect administrator password");
            return false; }}else {
        return false; }}Copy the code

Then check whether it is a user

Check whether the user name is registered

private boolean checkPassWord(a) {

    UserBean user = userBeanDao.userNameQuery(userName);
    if (user== null) {
        showTosat("User name not registered");
        return false;
    } else {
        if (user.getPassword().equals(passWord)) {
            // Correct password
            return true;
        } else {
            showTosat("Incorrect password");
            // Return false to reenter if incorrect
            return false; }}}Copy the code

Logic of registration

Check whether input is entered

/** * check *@return* /
private boolean checkContent(a){
    initInputData();
    if (TextUtils.isEmpty(userName))){
        showTosat("User name cannot be empty");
        return false;
    }
    if (TextUtils.isEmpty(passWord())){
        showTosat("Password cannot be empty.");
        return false;
    }
    if (TextUtils.isEmpty(phoneNumber))){
        showTosat("Cell phone number cannot be empty.");
        return false;
    }else {
        if(mViewModel.phoneNumber.get().length() ! =11 ) {
            showTosat("Incorrect phone number");
            return false; }}if (TextUtils.isEmpty(str_verification)){
        showTosat("Please enter the verification code.");
        return false;
    }else {
        if (str_verification.equals(verification) ) {
            showTosat("Verification code is not correct");
            return false; }}if(! mViewModel.passWord.get().equals(confirmPassword)){ showTosat("Two different passwords.");
        return false;
    }
    return true;
}
Copy the code

Check if you have registered

/** * Check if the user name is registered *@return* /
private boolean checkOnly(a){
    List<UserBean> data = userBeanDao.query();
    if (data == null) {return true;
    }
    for (UserBean userBean : data) {
        if (userBean.equals(mViewModel.userName.get())){
            return false; }}return true;
}
Copy the code

Obtain the verification code based on the mobile phone number

private void getVerification(a){

    if (TextUtils.isEmpty(mBinding.phoneNumberLayout.getEditText().getText().toString())){
        showTosat("Cell phone number cannot be empty.");
        return;
    }
    // Verification code countdown
    CountDownTimerUtils mCountDownTimerUtils = new CountDownTimerUtils( mBinding.btnGetVerification, 60000.1000);
    mCountDownTimerUtils.start();
    showTosat("【"+getString(R.string.app_name)+"Your registration verification code is:"+createVerification()+"Valid for 3 minutes!");
}


private int createVerification(a){
    int max=10000;
    int min=1000;
    Random random = new Random();
    verification =  (random.nextInt(max - min) + min + 1);
    return verification;
}
Copy the code

Preventing Memory leaks

FragmentDestroyView cleans up memory to prevent memory leaks

@Override
public void onDestroyView(a) {
    super.onDestroyView();
    mBinding = null;
    userBeanDao = null;
}
Copy the code
private void showTosat(String msg){
    Toast.makeText(getContext(), msg, Toast.LENGTH_LONG).show();
}
Copy the code

Captcha countdown

/** * @verification code countdown *@Author
 * @TimeAct 2022/2/25 * /
public class CountDownTimerUtils extends CountDownTimer {
    private Button mButton;

    / * * *@param textView          The TextView
     *
     *
     * @param millisInFuture    The number of millis in the future from the call
     *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
     *                          is called.
     * @param countDownInterval The interval along the way to receiver
     *                          {@link #onTick(long)} callbacks.
     */
    public CountDownTimerUtils(Button textView, long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        this.mButton = textView;
    }

    @Override
    public void onTick(long millisUntilFinished) {
        mButton.setEnabled(false); // The Settings are not clickable
        mButton.setText(millisUntilFinished / 1000 + "Resend in seconds.");  // Set the countdown time


        /** * URLSpan * Text background color BackgroundColorSpan * text color ForegroundColorSpan * Font size AbsoluteSizeSpan * Bold, italic StyleSpan * Strikethrough StrikethroughSpan * underline UnderlineSpan ImageSpan * http://blog.csdn.net/ah200614435/article/details/7914459 * / * image
        SpannableString spannableString = new SpannableString(mButton.getText().toString());  // Get the text on the button
        ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
        /** * public void setSpan(Object what, int start, int end, int flags) {* * starts at 0. End is the end position, so we're processing text that contains the start position, but not the end position. * /
        spannableString.setSpan(span, 0.2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);// Set the countdown time to red
        mButton.setText(spannableString);
    }

    @Override
    public void onFinish(a) {
        mButton.setText("Retrieve captcha code");
        mButton.setEnabled(true);// Retrieve the click}}Copy the code