本节内容
1.EditText简介
2.Button简介
3.Bomb三方库提供短信验证服务
4.首页布局
5.实现手机号自动分割
6.解决bug并删除号码
7.添加按钮界面跳转
8.使用selector设置按钮点击状态颜色
9.按钮文字颜色切换
10.解决格式化号码转换为正常号码bug
11.布局验证页面提示信息
12.将输入的内容显示到小方格中
13.Bmob环境搭建
14.请求验证码
15.验证输入的验证码
一、EditText简介
1.它可以监听文本改变的事件
mPhoneEditText.addTextChangedListener(object:LoginTextWatcher(){
override fun afterTextChanged(s: Editable?) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
}
-
这三个事件分别是: afterTextChanged(文本改变之后)、onTextChanged(文本正在改变)和beforeTextChanged(文本改变之前)
2.如果不想显示EditText中的光标,可以设置一下,将它去除
android:cursorVisible="false"
3.输入数字时,如果觉得数字间的间距很小,可以设置一下把间距加大
android:letterSpacing="0.1"
4.如果想要输入内容,但是又不想显示输入框,那么就可以将它的透明度设置得小一点,这样就可以将其隐藏起来。
android:alpha="0.01"
二、Button简介
1.通过text属性设置按钮的文本,颜色,文字大小等前面都讲过,这里就不再详述。
2.给按钮添加一个id之后,就可以给它设置点击事件了。
3.比较特别的按钮有switch,也可以给switch设置点击事件。switch有一个比较特别的属性就是isChecked。在手机的设置里面可能会使用到switch。
switch1.setOnClickListener {
val s = it as Switch
if(s.isChecked){
mLogin.text = "打开了"
}else{
mLogin.text = "关闭了"
}
}
4.还有checkBox按钮,这些属性都比较简单,可以自行琢磨。
三、Bmob三方库提供短信验证服务
1.先在Bmob注册一个账号,进入主页之后,点击左上角创建应用
2.回到网站首页,点击文档进入文档中心。然后点击数据服务的Android。
3.之后按照那一页的提示操作即可。
-
反正跟着它一路向下操作即可。
-
先在这里面添加底下那一行代码,也就是仓库地址
allprojects {
repositories {
//Bmob的maven仓库地址--必填
maven {url 'https://dl.bintray.com/chaozhouzhang/maven' }
-
然后在app的buildGradle的android里面添加依赖库
useLibrary 'org.apache.http.legacy'
-
然后在dependencies里面添加以下的依赖文件,然后同步一下。
implementation 'cn.bmob.android:bmob-sdk:3.7.8'
implementation "io.reactivex.rxjava2:rxjava:2.2.8"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'com.squareup.okhttp3:okhttp:3.14.1'
implementation 'com.squareup.okio:okio:2.2.2'
implementation 'com.google.code.gson:gson:2.8.5'
<!-- 允许联网 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 获取GSM(2g)、WCDMA(联通3g)等网络状态的信息 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 获取wifi网络状态的信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 保持CPU 运转,屏幕和键盘灯有可能是关闭的,用于文件上传和下载 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- 获取sd卡写的权限,用于文件上传和下载 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许读取手机状态 用于创建BmobInstallation -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<provider
android:name="cn.bmob.v3.util.BmobContentProvider"
android:authorities="com.example.message.BmobContentProvider"
android:exported="false">
</provider>
-
初始化Bomb,重新创建一个类,重写onCreate()方法
class MyApplication:Application() {
override fun onCreate() {
super.onCreate()
//第一.默认初始化
Bmob.initialize(this, "c12f5ff15568e1e18c72649071389bea");
}
}
-
Application ID从之前创建的应用的key里面查看。
-
通过 requestSMSCode 方式给绑定手机号的该用户发送指定短信模板的短信验证码:
/**
* TODO template 如果是自定义短信模板,此处替换为你在控制台设置的自定义短信模板名称;如果没有对应的自定义短信模板,则使用默认短信模板。
*/
BmobSMS.requestSMSCode(phone, "DataSDK", new QueryListener<Integer>() {
@Override
public void done(Integer smsId, BmobException e) {
if (e == null) {
mTvInfo.append("发送验证码成功,短信ID:" + smsId + "\n");
} else {
mTvInfo.append("发送验证码失败:" + e.getErrorCode() + "-" + e.getMessage() + "\n");
}
}
});
四、首页布局
我们要将界面布局成如下效果:
1.布局首页的时候,添加几个guideline,这样方便我们布局。
2.图片是一个正方形,我们之前讲过,在右侧属性中,点击那个矩形的左上角,让它的比例为1:1。
3.中间添加一个EditText,调节一下它的大小。
4.给输入框添加一个边框,所以在drawable中新建一个名为shape_roundrect的xml文件,然后把<selector>改为<shape>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp"/>
<stroke android:color="@color/colorGray"
android:width="1dp"/>
<solid android:color="@color/colorAlphaGray"/>
</shape>
5.然后找到EditText,把这个边框应用上
android:background="@drawable/shape_roundrect"
6.为了有更多的颜色可以选择,可以在values下添加一个colors.xml,在里面添加一些颜色
<resources>
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorAccent">#03DAC5</color>
<color name="colorGray">#666</color>
<color name="colorAlphaGray">#2666</color>
<color name="colorRed">#FF0000</color>
<color name="colorBlack">#000</color>
</resources>
7.想要输入框内部的内容和边框有一点间距,那么就可以设置一下padding。(自己和自己的间距)
android:paddingStart="10dp"
8.给输入框设置一下默认提示文字
android:hint="输入手机号"
五、实现手机号自动分割
1.我们平常输入手机号码时,都会自动分割为3 4 4 的形式。我们的实现思路为:时刻监听文本输入,当输入了三个数字之后添加一个空格,当输入八个字符之后,再添加一个空格。所以我们要给EditText添加一个监听事件,时刻监听它的变化。
mPhoneEditText.addTextChangedListener(object:LoginTextWatcher(){
override fun afterTextChanged(s: Editable?) {
//设置按钮是否可以点击
mLogin.isEnabled = (s.toString().length == 13)
//判断是在删除还是输入
if (!shouldAutoSplit) return
s.toString().length.also {
if (it == 3 || it == 8) {
//需要添加空格
s?.append(" ")
}
}
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
shouldAutoSplit =( count ==1)
}
})
2.对于TextWatcher监听器,我们只会用到其中的两个方法,但使用的时候还是不得不实现所有的方法。所以我们可以新建一个类,让它继承于TextWatcher,然后空实现这个接口的所有方法。后面新建的对象继承于我们创建的类即可。
3.新建一个类,继承TextWatcher。
open class LoginTextWatcher: TextWatcher{
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}
4.当字符串的长度为3和8时,需要添加空格。
s.toString().length.also {
if (it == 3 || it == 8) {
//需要添加空格
s?.append(" ")
}
}
5.因为输入的数字不超过11位,加上两个空格,就不超过13位。所以在EditText设置它的最大长度位13.
android:maxLength="13"
六、解决删除bug并获取号码
1.经过上面的操作,我们发现了一个bug。当我们发现输错号码,想要删除时,结果到了空格那里,发现空格删不掉。
-
因为当我们删到第八个的时候,它又执行afterTextChanged方法,结果发现长度为8,又添加一个空格,反反复复,所以删不掉。
2.实验过程中,我们发现,在 onTextChanged方法中,添加数字的时候 count = 1,删除数据的时候 count=0。所以我们可以根据count的值来判断用户是在增加还是删除。所以我们可以定义一个变量来记录这个。
private var shouldAutoSplit = true
3.在afterTextChanged方法中,加一个判断是在删除还是输入。如果是在输入的话,那么就执行下面的添加空格。如果是在删除的话,那么就return,就不会执行添加空格的操作。
if (!shouldAutoSplit) return
4.如果count = 1,那么就是在做增加,那么 shouldAutoSplit = true,否则就是false
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
shouldAutoSplit =( count ==1)
}
5.因为在输入的时候添加了空格,所以到时候传递过去的数据可能也包含空格。为了避免出现这种情况,我们就要把它转化为正常的数据。
private fun getPhoneNumber(editable: Editable):String{
//创建一个新的对象 用于操作editable对象里面的内容
SpannableStringBuilder(editable.toString()).also {
it.delete(3,4)
it.delete(7,8)
return it.toString()
}
}
七、添加按钮界面跳转
1.添加一个按钮,设置一个id,然后给它设置一个点击事件
2.因为要跳转到另外一个界面,所以我们要准备好另外一个界面。在这个监听事件中只需要启动一下页面即可。
mLogin.setOnClickListener{
Intent().apply {
//跳转方向
setClass(this@MainActivity,VerifyActivity::class.java)
//配置跳转携带的数据
putExtra("phone",getPhoneNumber(mPhoneEditText.text))
//启动
startActivity(this)
}
}
3.跳转过来的页面需要接收一下数据
intent.getStringExtra("phone").also {
//显示号码
mPhone.text = it
}
八、使用selector设置按钮点击状态颜色
1.输入手机号的时候,只有输入了13位手机号,登录按钮才会被点击,界面才会跳转。为了实现这个功能,我们设置一下按钮的enabled属性,当它为fasle的时候,按钮是不能被点击的。
android:enabled="false"
2.在afterTextChanged方法中设置按钮是否可以点击,只有当位数为13时,按钮才能被点击。
mLogin.isEnabled = (s.toString().length == 13)
3.为了让用户能够直观到感受到按钮能否被点击,我们可以让按钮在不同时刻变更不一样的颜色。所以我们在drawable中新建一个xml。enabled状态不同,显示的颜色也不同。这样就可以根据控件的状态,实现选择器的效果。
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--
根据控件的enable值 设置不同的颜色
注意顺序:特殊在前 常规在后
enable状态 运行起来正常状态 enable = true 其他状态 enable = false
从上至下匹配
-->
<item android:drawable="@color/colorAccent" android:state_enabled="true"/>
<item android:drawable="@color/colorAlphaGray" android:state_enabled="false"/>
</selector>
4.把selector整好了以后,在按钮那里使用起来,把它的背景选为这个xml文件
android:background="@drawable/btn_status_selector"
九、按钮文字颜色切换
1.为了美观,我们希望登录按钮文字的颜色也随用户的输入而变化,所以我们再创建一个xml。不能点击时,颜色为黑色。可以点击时,颜色为白色。
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/colorBlack"/>
<item android:state_enabled="true" android:color="@color/colorRed"/>
</selector>
2.在code再把textColor改为这个drawable中的文件
android:textColor="@drawable/btn_text_selector"
十、解决格式化号码转化为正常号码bug
1.bug:当我们输入号码时,它会按照3 4 4 的格式正常分割,然后我们进行界面跳转。再返回当前界面时,会发现显示的是去空格后格式化的号码,而不是3 4 4 形式的号码。
2.要避免出现这种情况,我们一开始就不能直接对editable进行操作。必须先把里面的东西取出来,然后再进行操作。所以我们用的是SpannableStringBuilder。
SpannableStringBuilder(editable.toString()).also {
it.delete(3,4)
it.delete(7,8)
return it.toString()
}
这就是前面我们这样使用的原因。
十一、布局验证页面提示信息
1.输入手机号之后,进入验证码验证页面,也就是输入验证码
2.上方图片调整为正方形,然后添加几个TextView即可。
3.输入验证码的地方有六个小边框,每个框框对应一个数字。最外面用一个EditText来包裹一下,小的框框是TextView。
4.添加六个TextView,让文字居中
android:gravity="center"
5.给这六个TextView添加六个边框,边框就是在drawable中新建一个xml,然后设置一下<shape>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke android:color="@color/colorPrimary" android:width="1dp"/>
<solid android:color="@color/colorAlphaGray"/>
<corners android:radius="6dp"/>
</shape>
6.然后在code里面把background设置为这个drawable中的文件。
7.拖动一个EditText,和这六个小框框重合,设置为match_parent,并设置其透明度为0.01
十二、将输入的内容显示到小方格中
1.给每个小框框添加id,为mv1——mv6。
2.让EditText中的内容显示到每一个小方框中的方法:EditText中是一串字符串,字符串又有索引。只需要将索引对应的字符作为每一个小的TextView中的Text即可。
3.保存所有显示验证码的textView
private val verifyViews:Array<TextView> by lazy {
arrayOf(mv1,mv2,mv3,mv4,mv5,mv6)
}
4.监听文本框内容改变的事件
mOrigin.addTextChangedListener(object:TextWatcher{
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}
5.这次我们只需要实现最后一个onTextChanged方法,所以后面的代码都是写在这个方法里面的。
6.将输入的内容拆分到每一个textView中,其中i是索引,item是字符。
for((i,item)in s?.withIndex()!!){
//获取i对应的textView
verifyViews[i].text = item.toString()
}
7.如果位数小于6个 后面的文本框不显示任何内容。
for(i in s.length..5){
verifyViews[i].text= ""
}
8.设置Edit Text文本框最长输入长度为6.
android:maxLength="6"
十三、Bmob环境搭建
1.当我们进入输入验证码的界面的时候,我们希望终端能自动向我们输入的号码发送短信。输入验证码之后,它又会将接收到的验证码和服务器发给用户的验证码进行比较,如果一致就返回一个结果,如果不一致就提示输入错误。这里我们就需要用到一个服务器发送短信。
2.关于配置数据库和依赖库等,我已经在前面写过了。其中配置的应用包名为applicationId后面显示的内容。
3.在Manifest里面配置一下name
android:name=".MyApplication"
十四、请求验证码
1.不让这个EditText被长按。
android:longClickable="false"
2.为了方便管理Bmob操作,我们创建一个类来管理关于Bmob的操作。
object BmobUtil {}
3.实现的功能就是①向服务器 请求发送验证码,完成之后有两个返回值(发送成功、发送失败)②验证用户输入的验证码 (验证成功 、验证失败)
4.先写一个发送验证码的方法,传递两个参数,第一个是手机号,第二个是回调的结果。我们这里用高阶函数作为返回的结果。
fun requestSMSCode(phone:String,callBack:(Int)->Unit){
BmobSMS.requestSMSCode(phone,"",object:QueryListener<Int>(){
override fun done(p0: Int?, p1: BmobException?) {
if(p1==null){
callBack(SUCCESS)
}else{
callBack(FAILURE)
}
}
} )
}
const val SUCCESS = 0
const val FAILURE = 1
5.对于客户端来说,只要调用我们这里写好的方法就可以发送短信了。
override fun onResume() {
super.onResume()
BmobUtil.requestSMSCode(mPhone.text.toString()){
if(it==BmobUtil.SUCCESS){
Toast.makeText(this,"发送验证码成功",Toast.LENGTH_SHORT).show()
}else{
Toast.makeText(this,"发送验证码失败",Toast.LENGTH_SHORT).show()
}
}
}
十五、验证输入的验证码
1.在BmobUtil 类中重写一下验证的方法。第一个参数为电话号码,第二个参数为用户输入的验证码,第三个参数为匿名内部类。
fun verifySMSCode(phone:String,code:String,callBack: (Int) -> Unit){
BmobSMS.verifySmsCode(phone,code,object :UpdateListener(){
override fun done(p0: BmobException?) {
if(p0==null){
//验证码验证成功
callBack(SUCCESS)
}else{
//验证失败
callBack(FAILURE)
}
}
})
}
2.发送验证请求之后,再判断验证成功与否。如果成功,则进行界面跳转。如果失败就提示一下,并清空文本框中的内容。
if(s.length==6){
//发起验证的请求
BmobUtil.verifySMSCode(mPhone.text.toString(),s.toString()){
if(it==BmobUtil.SUCCESS){
startActivity(Intent(this@VerifyActivity,HomeActivity::class.java))
}else{
Toast.makeText(this@VerifyActivity,"验证失败",Toast.LENGTH_SHORT).show()
mOrigin.text.clear()
}
}
}
3.自己创建一个简单的页面,作为验证成功后跳转的界面。就改一下背景颜色即可。只要能分辨得出和前面的页面不一样都行。之后在manifest中注册一下。
<activity android:name=".HomeActivity"/>
所有的操作基本完成,我们运行之后,发送短信,如果是正确的号码,就会收到这样的短信。