IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【Android】登录实战 -> 正文阅读

[移动开发]【Android】登录实战

效果视频

【Android】登录实战效果视频

ViewPager+TabLayout+PagerAdapter

简述

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

 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 );
    }
}

添加视图与标题

创建视图操作对象

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("注册账号");
Title.add("忘记密码");

视图与标题双向绑定

RegisterAddForgetAdapter adapter = new RegisterAddForgetAdapter(views, Title);
        for (String title : Title) {
            TotalTitle.addTab(TotalTitle.newTab().setText(title));
        }
        TotalTitle.setupWithViewPager(viewPager);
        viewPager.setAdapter(adapter);

TabLayout样式设置

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

选择器

两个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"/>
</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"
        />
</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("手机号码不能为空");
            //processError("手机号码不能为空");
            RPhoneNumber.setText("");
            return false;
        }
        if (TextUtils.isEmpty(Code)) {
            toastUtils.ShowWarn("验证码不能为空");
            //processError("手机号码不能为空");
            RVerificationCode.setText("");
            return false;
        }
        if (TextUtils.isEmpty(PassWord)) {
            toastUtils.ShowWarn("密码不能为空");
            //processError("密码不能为空");
            RNewPassWord.setText("");
            return false;
        }
        if (PassWord.length() < 6 || PassWord.length() > 18) {
            toastUtils.ShowWarn("密码只能在6-18位");
            //processError("密码只能在6-18位");
            RNewPassWord.setText("");
            return false;
        }
        if (!JudgePhoneNumberLength(PhoneNumber)) {
            toastUtils.ShowWarn("手机号码只能为11位");
            //processError("手机号码只能为11位");
            //RPhoneNumber.setText("");
            return false;
        }
        if (JudgePhoneNumberFormat(PhoneNumber)) {
            toastUtils.ShowWarn("手机号码格式错误");
            // processError("手机号码格式错误");
            //RPhoneNumber.setText("");
            return false;
        }
        if (!CheckBoxFlag) {
            toastUtils.ShowWarn("请先勾选隐私服务");
            //processError("请先勾选隐私服务");
            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())) {
                    //如果账号已存在
                    toastUtils.ShowFail("手机号码已经被注册");
                    return false;
                }
            }
        }
        return true;
    }

手机号码格式判定

正则表达式判定手机格式

使用正则表达式对手机号码进行格式判定,其格式为第一位必须为1第2位必须为345789其中一位后面9位可以为0-9任意一位

    /*一、中国电信号段:
133、153、173、177、180、181、189、191、199
二、中国联通号段:
130、131、132、155、156、166、175、176、185、186
三、中国移动号段:
134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、178、182、183、184、187、188、198*/
    private boolean JudgePhoneNumberFormat(String Number) {
        //第一位必须为1,第二位为345789其中一位,后面九位从0-9都可以
        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())) {
                    //如果账号已存在
                    toastUtils.ShowFail("手机号码已经被注册");
                    return false;
                }
            }
        }

验证码

获取验证码

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

String PhoneNumber = ForgetPhone.getText().toString();
                if ((!JudgePhoneNumberFormat(PhoneNumber)) && (!JudgePhoneNumberLength(PhoneNumber))) {
                    toastUtils.ShowFail("手机号码格式错误");
                    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("验证码");
                    handlerFlag = false;
                    Current = 60;
                }
            }else {
                RGetCode.setEnabled(true);
                RGetCode.setText("验证码");
                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 此处为子线程!不可直接处理UI线程!处理后续操作需传到主线程中操作!
                if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {
                    if (result == SMSSDK.RESULT_COMPLETE) {
                        runOnUiThread(() -> {
                            if (FuncFlag){
                                RegisterSuccess();
                            }else {
                                ResetSuccess();
                            }
                            //toastUtils.ShowSuccess("验证成功");
                        });
                    } else {
                        runOnUiThread(() -> {
                            //processError("验证码不匹配");
                            toastUtils.ShowFail("验证码不匹配");
                        });
                    }
                } else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) {
                    runOnUiThread(() -> {
                        //processError("获取短信验证码成功");
                        toastUtils.ShowSuccess("获取短信验证码成功");
                    });
                } else {
                    runOnUiThread(() -> {
                        //processError("异常");
                        toastUtils.ShowFail("异常");
                    });
                    ((Throwable) data).printStackTrace();
                }
         }
        };

注册成功

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

    private void RegisterSuccess() {
        handlerFlag = false;
        toastUtils.ShowSuccess("注册成功");
        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"/>
</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"/>
</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("重置密码成功");
        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("登录成功");
                    dao.UpdateStatus(GetPhoneNumber, 1);
                    sp.PutData(Login.this, "PhoneNumber", GetPhoneNumber);
                    startActivity(new Intent(Login.this, MainActivity.class));
                    return;
                }
            }
            toastUtils.ShowFail("账号或密码错误");
        } else {
            toastUtils.ShowFail("异常");
        }

尾言

验证码API用的是MobService,收费是0.03一条,官网有详细配置步骤,有意者可以去了解

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-27 11:27:30  更:2022-04-27 11:28:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 23:26:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码