「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战
上一篇文章演示的SQLite的使用,本篇文章就是登录的实战了
viewBinding
使用viewBinding干掉findViewById()
android {
...
buildFeatures {
viewBinding true
}
}
复制代码
登录的Activity
LoginActivity的布局文件,里面就一个FrameLayout,登录注册的界面都是Fragment
<?xml version="1.0" encoding="utf-8"?>
<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>
复制代码
LoginActivity布局文件的Binding
private ActivityLoginBinding mBinding;
复制代码
创建布局
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();
}
复制代码
登录的逻辑
public class LoginFragment extends Fragment {
private FragmentLoginBinding mBinding;
public static LoginFragment newInstance() {
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();
}
复制代码
注册的点击事件
请求父布局管理器替换当前页面来执行事务
mBinding.btnRegister.setOnClickListener(v -> {
RegisterFragment registerFragment = RegisterFragment.newInstance();
getParentFragmentManager()
.beginTransaction()
//Fragment切换的左右平滑动画
.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();
});
复制代码
我们先假设已经注册好了
那么登录逻辑先判断是否输入再利用用户名来验证密码是否正确
管理员账号密码
public static final String AdminUserName = "admin";
public static final String AdminUserPassWord = "123456";
复制代码
//登录
mBinding.btnLogin.setOnClickListener(v -> {
if (checkContent()) {
//是否是管理员账号
if (userName.equals(Constant.AdminUserName)) {
if (checkAdminPassWord()) {
//管理员密码正确
}
}else if (checkPassWord()) {
//用户密码正确
}
}
});
复制代码
/**
* 检查是否输入
*
* @return
*/
private boolean checkContent() {
userName = mBinding.etUsernameLayout.getEditText().getText().toString();
passWord = mBinding.etPasswordLayout.getEditText().getText().toString();
if (TextUtils.isEmpty(userName)) {
showTosat("用户名不能为空");
return false;
}
if (TextUtils.isEmpty(userName)) {
showTosat("密码不能为空");
return false;
}
return true;
}
复制代码
先判断是否是管理员
检测管理员密码
private boolean checkAdminPassWord() {
if (userName.equals(Constant.AdminUserName)) {
if (passWord.equals(Constant.AdminUserPassWord)) {
return true;
} else {
showTosat("管理员密码不正确");
return false;
}
} else {
return false;
}
}
复制代码
再判断是否是用户
检测用户名是否注册
private boolean checkPassWord() {
UserBean user = userBeanDao.userNameQuery(userName);
if (user== null) {
showTosat("用户名未注册");
return false;
} else {
if (user.getPassword().equals(passWord)) {
//密码正确
return true;
} else {
showTosat("密码不正确");
//不正确返回false重新输入
return false;
}
}
}
复制代码
注册的逻辑
先检测是否输入
扫描二维码关注公众号,回复:
13690949 查看本文章
/**
* 检查
* @return
*/
private boolean checkContent(){
initInputData();
if (TextUtils.isEmpty(userName))){
showTosat("用户名不能为空");
return false;
}
if (TextUtils.isEmpty(passWord())){
showTosat("密码不能为空");
return false;
}
if (TextUtils.isEmpty(phoneNumber))){
showTosat("手机号不能为空");
return false;
}else {
if (mViewModel.phoneNumber.get().length() != 11 ) {
showTosat("手机号不正确");
return false;
}
}
if (TextUtils.isEmpty(str_verification)){
showTosat("请输入验证码");
return false;
}else {
if (str_verification.equals(verification) ) {
showTosat("验证码不正确");
return false;
}
}
if (!mViewModel.passWord.get().equals(confirmPassword)){
showTosat("两次密码不一致");
return false;
}
return true;
}
复制代码
检查是否已经注册
/**
* 检查是用户名是否已经注册
* @return
*/
private boolean checkOnly(){
List<UserBean> data = userBeanDao.query();
if (data == null){
return true;
}
for (UserBean userBean : data) {
if (userBean.equals(mViewModel.userName.get())){
return false;
}
}
return true;
}
复制代码
根据手机号获取验证码
private void getVerification(){
if (TextUtils.isEmpty(mBinding.phoneNumberLayout.getEditText().getText().toString())){
showTosat("手机号不能为空");
return;
}
//验证码倒计时
CountDownTimerUtils mCountDownTimerUtils = new CountDownTimerUtils( mBinding.btnGetVerification, 60000, 1000);
mCountDownTimerUtils.start();
showTosat("【"+getString(R.string.app_name)+"】你的注册验证码是:"+createVerification()+",3分钟内有效!");
}
private int createVerification(){
int max=10000;
int min=1000;
Random random = new Random();
verification = (random.nextInt(max - min) + min + 1);
return verification;
}
复制代码
防止内存泄露
fragmentDestroyView时清理内存防止内存泄露
@Override
public void onDestroyView() {
super.onDestroyView();
mBinding = null;
userBeanDao = null;
}
复制代码
private void showTosat(String msg){
Toast.makeText(getContext(), msg, Toast.LENGTH_LONG).show();
}
复制代码
验证码倒计时
/**
* @验证码倒计时
* @Author
* @Time 2022/2/25 21:15
*/
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); //设置不可点击
mButton.setText(millisUntilFinished / 1000 + "秒后可重新发送"); //设置倒计时时间
/**
* 超链接 URLSpan
* 文字背景颜色 BackgroundColorSpan
* 文字颜色 ForegroundColorSpan
* 字体大小 AbsoluteSizeSpan
* 粗体、斜体 StyleSpan
* 删除线 StrikethroughSpan
* 下划线 UnderlineSpan
* 图片 ImageSpan
* http://blog.csdn.net/ah200614435/article/details/7914459
*/
SpannableString spannableString = new SpannableString(mButton.getText().toString()); //获取按钮上的文字
ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
/**
* public void setSpan(Object what, int start, int end, int flags) {
* 主要是start跟end,start是起始位置,无论中英文,都算一个。
* 从0开始计算起。end是结束位置,所以处理的文字,包含开始位置,但不包含结束位置。
*/
spannableString.setSpan(span, 0, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);//将倒计时的时间设置为红色
mButton.setText(spannableString);
}
@Override
public void onFinish() {
mButton.setText("重新获取验证码");
mButton.setEnabled(true);//重新获得点击
}
}
复制代码