【Android】登录实战

效果视频

通过此架构将注册界面与忘记密码进行滑动绑定
导入如下闭包即可 使用

 implementation 'com.google.android.material:material:1.1.0-alpha09'
 implementation 'com.google.android.material:material:1.0.0'

通过继承 PagerAdapter类,将需要插入的视图与标题通过 List传入

public class RegisterAddForgetAdapter extends PagerAdapter {
    private List<view> views;
    private List<string> FragmentString;

   public RegisterAddForgetAdapter(List<view> views, List<string> FragmentString){
       this.views = views;
       this.FragmentString = FragmentString;
   }

    @Override
    public int getCount() {
        return views.size();
    }

    @Override
    public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
        return view == object;
    }

    @NonNull
    @Override
    public Object instantiateItem(@NonNull ViewGroup container, int position) {
        container.addView( views.get( position ) );
        return views.get( position );
    }

    @Override
    public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
        container.removeView( views.get( position ) );
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        return FragmentString.get( position );
    }
}

</string></view></string></view>

创建视图操作对象

View viewRegister = LayoutInflater.from(RegisterADDForget.this).inflate(R.layout.register_prepare, null);

View viewForget = LayoutInflater.from(RegisterADDForget.this).inflate(R.layout.forget_item, null);

添加视图与标题

views.add(viewRegister);
views.add(viewForget);
Title.add("&#x6CE8;&#x518C;&#x8D26;&#x53F7;");
Title.add("&#x5FD8;&#x8BB0;&#x5BC6;&#x7801;");
RegisterAddForgetAdapter adapter = new RegisterAddForgetAdapter(views, Title);
        for (String title : Title) {
            TotalTitle.addTab(TotalTitle.newTab().setText(title));
        }
        TotalTitle.setupWithViewPager(viewPager);
        viewPager.setAdapter(adapter);

通过创建一个选择器在不同条件触发不同效果,当未被选中时,为灰色,当被选中时为蓝色

两个 drawable样式文件就不贴出了,就改变背景颜色和圆角弧度两个操作

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/indicator" android:state_selected="true">
    <item android:drawable="@drawable/un_indicator">
</item></item></selector>

在将外层布局设置成灰色,其灰色程度高于默认选择器灰色,形成一个颜色对比
有几个关键点
一、需要将 TabLayout默认滑块的高度设为0

    app:tabIndicatorHeight="0dp"

二、滑块居中

 app:tabMode="fixed"
 app:tabGravity="center"
<linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:background="@drawable/tablayout_style" android:layout_marginleft="60dp" android:layout_marginright="60dp" android:layout_margintop="20dp" android:padding="10dp">
    <com.google.android.material.tabs.tablayout android:id="@+id/TotalTitle" android:layout_width="match_parent" android:layout_height="30dp" app:tabselectedtextcolor="#ffffff" app:tabtextcolor="#A59C9C" app:tabmode="fixed" app:tabbackground="@drawable/selector" app:tabindicatorheight="0dp" app:tabgravity="center" app:tabindicatorfullwidth="false">
</com.google.android.material.tabs.tablayout></linearlayout>

对用户输入的注册信息进行简单判空和格式判定

 private boolean Information() {
        informationList = dao.QueryAll();
     //Toast.makeText(RegisterADDForget.this,informationList.size()+"",Toast.LENGTH_LONG).show();
        //String Name = RegisterUser.getText().toString();
        PassWord = RNewPassWord.getText().toString();
        PhoneNumber = RPhoneNumber.getText().toString().trim();
        String Code = RVerificationCode.getText().toString().trim();
        //String Sex = RegisterSex.getText().toString();
        if (TextUtils.isEmpty(PhoneNumber)) {
            toastUtils.ShowWarn("&#x624B;&#x673A;&#x53F7;&#x7801;&#x4E0D;&#x80FD;&#x4E3A;&#x7A7A;");
            //processError("&#x624B;&#x673A;&#x53F7;&#x7801;&#x4E0D;&#x80FD;&#x4E3A;&#x7A7A;");
            RPhoneNumber.setText("");
            return false;
        }
        if (TextUtils.isEmpty(Code)) {
            toastUtils.ShowWarn("&#x9A8C;&#x8BC1;&#x7801;&#x4E0D;&#x80FD;&#x4E3A;&#x7A7A;");
            //processError("&#x624B;&#x673A;&#x53F7;&#x7801;&#x4E0D;&#x80FD;&#x4E3A;&#x7A7A;");
            RVerificationCode.setText("");
            return false;
        }
        if (TextUtils.isEmpty(PassWord)) {
            toastUtils.ShowWarn("&#x5BC6;&#x7801;&#x4E0D;&#x80FD;&#x4E3A;&#x7A7A;");
            //processError("&#x5BC6;&#x7801;&#x4E0D;&#x80FD;&#x4E3A;&#x7A7A;");
            RNewPassWord.setText("");
            return false;
        }
        if (PassWord.length() < 6 || PassWord.length() > 18) {
            toastUtils.ShowWarn("&#x5BC6;&#x7801;&#x53EA;&#x80FD;&#x5728;6-18&#x4F4D;");
            //processError("&#x5BC6;&#x7801;&#x53EA;&#x80FD;&#x5728;6-18&#x4F4D;");
            RNewPassWord.setText("");
            return false;
        }
        if (!JudgePhoneNumberLength(PhoneNumber)) {
            toastUtils.ShowWarn("&#x624B;&#x673A;&#x53F7;&#x7801;&#x53EA;&#x80FD;&#x4E3A;11&#x4F4D;");
            //processError("&#x624B;&#x673A;&#x53F7;&#x7801;&#x53EA;&#x80FD;&#x4E3A;11&#x4F4D;");
            //RPhoneNumber.setText("");
            return false;
        }
        if (JudgePhoneNumberFormat(PhoneNumber)) {
            toastUtils.ShowWarn("&#x624B;&#x673A;&#x53F7;&#x7801;&#x683C;&#x5F0F;&#x9519;&#x8BEF;");
            // processError("&#x624B;&#x673A;&#x53F7;&#x7801;&#x683C;&#x5F0F;&#x9519;&#x8BEF;");
            //RPhoneNumber.setText("");
            return false;
        }
        if (!CheckBoxFlag) {
            toastUtils.ShowWarn("&#x8BF7;&#x5148;&#x52FE;&#x9009;&#x9690;&#x79C1;&#x670D;&#x52A1;");
            //processError("&#x8BF7;&#x5148;&#x52FE;&#x9009;&#x9690;&#x79C1;&#x670D;&#x52A1;");
            RCheckBox.setChecked(false);
            CheckBoxFlag = false;
            return false;
        }

        if (informationList != null) {
            for (int i = 0; i < informationList.size(); i++) {
                if (PhoneNumber.equals(informationList.get(i).getPhone())) {
                    //&#x5982;&#x679C;&#x8D26;&#x53F7;&#x5DF2;&#x5B58;&#x5728;
                    toastUtils.ShowFail("&#x624B;&#x673A;&#x53F7;&#x7801;&#x5DF2;&#x7ECF;&#x88AB;&#x6CE8;&#x518C;");
                    return false;
                }
            }
        }
        return true;
    }

使用正则表达式对手机号码进行格式判定,其格式为 &#x7B2C;&#x4E00;&#x4F4D;&#x5FC5;&#x987B;&#x4E3A;1&#x7B2C;2&#x4F4D;&#x5FC5;&#x987B;&#x4E3A;345789&#x5176;&#x4E2D;&#x4E00;&#x4F4D;&#x540E;&#x9762;9&#x4F4D;&#x53EF;&#x4EE5;&#x4E3A;0-9&#x4EFB;&#x610F;&#x4E00;&#x4F4D;

    /*&#x4E00;&#x3001;&#x4E2D;&#x56FD;&#x7535;&#x4FE1;&#x53F7;&#x6BB5;&#xFF1A;
133&#x3001;153&#x3001;173&#x3001;177&#x3001;180&#x3001;181&#x3001;189&#x3001;191&#x3001;199
&#x4E8C;&#x3001;&#x4E2D;&#x56FD;&#x8054;&#x901A;&#x53F7;&#x6BB5;:
130&#x3001;131&#x3001;132&#x3001;155&#x3001;156&#x3001;166&#x3001;175&#x3001;176&#x3001;185&#x3001;186
&#x4E09;&#x3001;&#x4E2D;&#x56FD;&#x79FB;&#x52A8;&#x53F7;&#x6BB5;:
134(0-8)&#x3001;135&#x3001;136&#x3001;137&#x3001;138&#x3001;139&#x3001;147&#x3001;150&#x3001;151&#x3001;152&#x3001;157&#x3001;158&#x3001;159&#x3001;178&#x3001;182&#x3001;183&#x3001;184&#x3001;187&#x3001;188&#x3001;198*/
    private boolean JudgePhoneNumberFormat(String Number) {
        //&#x7B2C;&#x4E00;&#x4F4D;&#x5FC5;&#x987B;&#x4E3A;1&#xFF0C;&#x7B2C;&#x4E8C;&#x4F4D;&#x4E3A;345789&#x5176;&#x4E2D;&#x4E00;&#x4F4D;&#xFF0C;&#x540E;&#x9762;&#x4E5D;&#x4F4D;&#x4ECE;0-9&#x90FD;&#x53EF;&#x4EE5;
        String NumberFormat = "[1][345789]\\d[9]";
        if (TextUtils.isEmpty(Number)) {
            return false;
        } else {
            return Number.matches(NumberFormat);
        }
    }
public boolean JudgePhoneNumberLength(String Number) {
        if (TextUtils.isEmpty(Number)) {
            return false;
        } else {
            return Number.length() == 11 ? true : false;
        }
    }

通过对 SQLite数据库进行全部记录查询,并返回一个实体类数组

 informationList = dao.QueryAll();

然后对其进行一个顺序查找遍历,并根据判定结果,做出相对于的可视化提示提醒用户

 if (informationList != null) {
            for (int i = 0; i < informationList.size(); i++) {
                if (PhoneNumber.equals(informationList.get(i).getPhone())) {
                    //&#x5982;&#x679C;&#x8D26;&#x53F7;&#x5DF2;&#x5B58;&#x5728;
                    toastUtils.ShowFail("&#x624B;&#x673A;&#x53F7;&#x7801;&#x5DF2;&#x7ECF;&#x88AB;&#x6CE8;&#x518C;");
                    return false;
                }
            }
        }

如果注册信息符合设定的标准,就通过异步通信 HandlerMessageQueue进行验证码获取

String PhoneNumber = ForgetPhone.getText().toString();
                if ((!JudgePhoneNumberFormat(PhoneNumber)) && (!JudgePhoneNumberLength(PhoneNumber))) {
                    toastUtils.ShowFail("&#x624B;&#x673A;&#x53F7;&#x7801;&#x683C;&#x5F0F;&#x9519;&#x8BEF;");
                    handlerFlag = false;
                } else {
                    handlerFlag = true;
                    SMSSDK.getVerificationCode("86", PhoneNumber);
                    handler.sendEmptyMessageDelayed(0, 1000);
                    Log.d("RegisterAddForget", "successClickCodeButton");
                }

当点击获取验证码按钮之后,对其进行一个读秒设置,并通过 Handler不断在用户视图中修改其秒值,归0之后,解锁按钮,并恢复成初始化

Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            if (handlerFlag) {
                if (Current > 0) {
                    Current--;
                    RGetCode.setEnabled(false);
                    RGetCode.setText("(" + Current + "s)");
                    sendEmptyMessageDelayed(0, 1000);
                    Log.d("RegisterAddForget", Current + "S");
                } else {
                    RGetCode.setEnabled(true);
                    RGetCode.setText("&#x9A8C;&#x8BC1;&#x7801;");
                    handlerFlag = false;
                    Current = 60;
                }
            }else {
                RGetCode.setEnabled(true);
                RGetCode.setText("&#x9A8C;&#x8BC1;&#x7801;");
                handlerFlag = false;
                Current = 60;
            }
        }
    };

如果成功获取验证码,则提交验证码,判定是否一致

 boolean result = Information();
  if (result) {
 /**register success*/
FuncFlag = true;
String PhoneNumber = RPhoneNumber.getText().toString().trim();
String Code = RVerificationCode.getText().toString().trim();
submitVerificationCode("86", PhoneNumber, Code);
   }
public static void submitVerificationCode(String Country, String Phone, String Code) {
 SMSSDK.submitVerificationCode(Country, Phone, Code);
    }

通过判定回调的标识符,判定验证码是否一致

eh = new EventHandler() {
            @Override
            public void afterEvent(int event, int result, Object data) {
                // TODO &#x6B64;&#x5904;&#x4E3A;&#x5B50;&#x7EBF;&#x7A0B;&#xFF01;&#x4E0D;&#x53EF;&#x76F4;&#x63A5;&#x5904;&#x7406;UI&#x7EBF;&#x7A0B;&#xFF01;&#x5904;&#x7406;&#x540E;&#x7EED;&#x64CD;&#x4F5C;&#x9700;&#x4F20;&#x5230;&#x4E3B;&#x7EBF;&#x7A0B;&#x4E2D;&#x64CD;&#x4F5C;&#xFF01;
                if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
                    if (result == SMSSDK.RESULT_COMPLETE) {
                        runOnUiThread(() -> {
                            if (FuncFlag){
                                RegisterSuccess();
                            }else {
                                ResetSuccess();
                            }
                            //toastUtils.ShowSuccess("&#x9A8C;&#x8BC1;&#x6210;&#x529F;");
                        });
                    } else {
                        runOnUiThread(() -> {
                            //processError("&#x9A8C;&#x8BC1;&#x7801;&#x4E0D;&#x5339;&#x914D;");
                            toastUtils.ShowFail("&#x9A8C;&#x8BC1;&#x7801;&#x4E0D;&#x5339;&#x914D;");
                        });
                    }
                } else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) {
                    runOnUiThread(() -> {
                        //processError("&#x83B7;&#x53D6;&#x77ED;&#x4FE1;&#x9A8C;&#x8BC1;&#x7801;&#x6210;&#x529F;");
                        toastUtils.ShowSuccess("&#x83B7;&#x53D6;&#x77ED;&#x4FE1;&#x9A8C;&#x8BC1;&#x7801;&#x6210;&#x529F;");
                    });
                } else {
                    runOnUiThread(() -> {
                        //processError("&#x5F02;&#x5E38;");
                        toastUtils.ShowFail("&#x5F02;&#x5E38;");
                    });
                    ((Throwable) data).printStackTrace();
                }
         }
        };

若注册成功,即将用户输入的信息插入数据库中

    private void RegisterSuccess() {
        handlerFlag = false;
        toastUtils.ShowSuccess("&#x6CE8;&#x518C;&#x6210;&#x529F;");
        dao.Insert(new Information("", PassWord, "", PhoneNumber, "DefaultCity", "000000", 0, 0, 0));
        handler.sendEmptyMessageDelayed(0, 1000);
    }

忘记密码和注册差不多,对输入的信息进行格式判定、验证码的获取,提交,判定等流程,此处省略相同部分

为了优化用户体验,通过对重置密码按钮进行背景变化设置,当没有输入任何字符时,默认呈灰色,当输入字符时,自动变为蓝色

选择状态

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="#2196F3">
    <corners android:radius="10dp">
</corners></solid></shape>

默认灰色

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <corners android:radius="10dp">
    <solid android:color="#F8F7F7">
</solid></corners></shape>

通过对 EditText进行点击事件监听,然后在不同条件下触发不同效果

RPhoneNumber.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                Log.d("RegisterAddForget", s.toString() + "-before");

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if (s.length() > 0) {
                    ConfirmRegister.setEnabled(true);
                    ConfirmRegister.setClickable(true);
                    ConfirmRegister.setBackground(getResources().getDrawable(R.drawable.btn_blue_rd));
                    ConfirmRegister.setTextColor(Color.parseColor("#ffffff"));
                } else {
                    ConfirmRegister.setEnabled(false);
                    ConfirmRegister.setClickable(false);
                    ConfirmRegister.setBackground(getResources().getDrawable(R.drawable.bt_not_sure));
                    ConfirmRegister.setTextColor(Color.parseColor("#DAD7D7"));
                }
                Log.d("RegisterAddForget", s.toString() + "-Changed");

            }

            @Override
            public void afterTextChanged(Editable s) {
                Log.d("RegisterAddForget", s.toString() + "-after");
            }
        });

对数据库该记录进行更新操作

    private void ResetSuccess(){
        handlerFlag = false;
        toastUtils.ShowSuccess("&#x91CD;&#x7F6E;&#x5BC6;&#x7801;&#x6210;&#x529F;");
        dao.UpdatePassWord(ResetPhoneNumber,NewPassWord);
        handler.sendEmptyMessageDelayed(0, 1000);
    }

登录功能为根据用户输入的数据对数据库进行查询,然后根据返回的实体类数组进行顺序遍历,然后判定是否匹配,并做出相对应的操作

判空处理,手机号码格式判定就省略了,上述中提及过,以下为对实体类数组进行顺序查询判定,如果存在匹配项则更改该记录的登录状态标志符,方便在主界面以及个人信息界面根据此标志符进行判定是否显示、读取数据,如果不存在匹配项,则触发相对应的条件,并显示在用户界面上

if (informationList != null) {
            Log.d("Login","get into if");
            Log.d("Login",informationList.size() +"size");
            for (int i = 0; i < informationList.size(); i++) {
                Log.d("Login","get into for");
                if ((GetPhoneNumber.equals(informationList.get(i).getPhone())) && (GetPassWordEdit.equals(informationList.get(i).getPassWord()))) {
                    toastUtils.ShowSuccess("&#x767B;&#x5F55;&#x6210;&#x529F;");
                    dao.UpdateStatus(GetPhoneNumber, 1);
                    sp.PutData(Login.this, "PhoneNumber", GetPhoneNumber);
                    startActivity(new Intent(Login.this, MainActivity.class));
                    return;
                }
            }
            toastUtils.ShowFail("&#x8D26;&#x53F7;&#x6216;&#x5BC6;&#x7801;&#x9519;&#x8BEF;");
        } else {
            toastUtils.ShowFail("&#x5F02;&#x5E38;");
        }

Original: https://blog.csdn.net/News53231323/article/details/124371529
Author: FranzLiszt1847
Title: 【Android】登录实战

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/816387/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球