parent
98e8fdbb33
commit
59f950915a
@ -0,0 +1,15 @@ |
||||
package xyz.fycz.myreader.base |
||||
|
||||
import android.text.TextWatcher |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2021/12/9 12:32 |
||||
*/ |
||||
abstract class MyTextWatcher : TextWatcher { |
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { |
||||
} |
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { |
||||
} |
||||
} |
@ -0,0 +1,10 @@ |
||||
package xyz.fycz.myreader.model.user |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2021/12/9 10:19 |
||||
*/ |
||||
data class Result( |
||||
val code: Int, |
||||
val result: Any |
||||
) |
@ -0,0 +1,70 @@ |
||||
package xyz.fycz.myreader.model.user; |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2020/7/12 17:35 |
||||
*/ |
||||
public class User { |
||||
private Integer userId; |
||||
private String userName; |
||||
private String password; |
||||
private String email; |
||||
|
||||
public User() { |
||||
} |
||||
|
||||
public User(String userName) { |
||||
this.userName = userName; |
||||
} |
||||
|
||||
public User(String userName, String password) { |
||||
this.userName = userName; |
||||
this.password = password; |
||||
} |
||||
|
||||
public User(String userName, String password, String email) { |
||||
this.userName = userName; |
||||
this.password = password; |
||||
this.email = email; |
||||
} |
||||
|
||||
public User(Integer userId, String userName, String password, String email) { |
||||
this.userId = userId; |
||||
this.userName = userName; |
||||
this.password = password; |
||||
this.email = email; |
||||
} |
||||
|
||||
|
||||
public Integer getUserId() { |
||||
return userId; |
||||
} |
||||
|
||||
public String getUserName() { |
||||
return userName; |
||||
} |
||||
|
||||
public void setUserName(String userName) { |
||||
this.userName = userName; |
||||
} |
||||
|
||||
public String getPassword() { |
||||
return password; |
||||
} |
||||
|
||||
public void setPassword(String password) { |
||||
this.password = password; |
||||
} |
||||
|
||||
public void setUserId(Integer userId) { |
||||
this.userId = userId; |
||||
} |
||||
|
||||
public String getEmail() { |
||||
return email; |
||||
} |
||||
|
||||
public void setEmail(String email) { |
||||
this.email = email; |
||||
} |
||||
} |
@ -0,0 +1,171 @@ |
||||
package xyz.fycz.myreader.model.user |
||||
|
||||
import io.reactivex.Single |
||||
import io.reactivex.SingleOnSubscribe |
||||
import okhttp3.MediaType |
||||
import okhttp3.RequestBody |
||||
import xyz.fycz.myreader.application.App |
||||
import xyz.fycz.myreader.common.APPCONST |
||||
import xyz.fycz.myreader.common.URLCONST |
||||
import xyz.fycz.myreader.model.storage.Backup |
||||
import xyz.fycz.myreader.model.storage.Restore |
||||
import xyz.fycz.myreader.model.storage.Restore.restore |
||||
import xyz.fycz.myreader.util.* |
||||
import xyz.fycz.myreader.util.utils.FileUtils |
||||
import xyz.fycz.myreader.util.utils.GSON |
||||
import xyz.fycz.myreader.util.utils.OkHttpUtils |
||||
import xyz.fycz.myreader.util.utils.RxUtils |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2021/12/9 10:17 |
||||
*/ |
||||
object UserService2 { |
||||
fun login(user: User): Single<Result> { |
||||
return Single.create(SingleOnSubscribe<Result> { |
||||
val mediaType = MediaType.parse("application/x-www-form-urlencoded") |
||||
val body = "username=${user.userName}" + |
||||
"&password=${user.password}" + |
||||
makeAuth() |
||||
val requestBody = RequestBody.create(mediaType, body) |
||||
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/login", requestBody, "UTF-8") |
||||
it.onSuccess(GSON.fromJson(ret, Result::class.java)) |
||||
}).compose { RxUtils.toSimpleSingle(it) } |
||||
} |
||||
|
||||
fun register(user: User, code: String, keyc: String): Single<Result> { |
||||
return Single.create(SingleOnSubscribe<Result> { |
||||
val mediaType = MediaType.parse("application/x-www-form-urlencoded") |
||||
val body = "username=${user.userName}" + |
||||
"&password=${user.password}" + |
||||
"&email=${user.email}" + |
||||
"&code=${code}" + |
||||
"&keyc=${keyc}" + |
||||
"&key=${CyptoUtils.encode(APPCONST.KEY, APPCONST.publicKey)}" + |
||||
makeAuth() |
||||
val requestBody = RequestBody.create(mediaType, body) |
||||
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/reg", requestBody, "UTF-8") |
||||
it.onSuccess(GSON.fromJson(ret, Result::class.java)) |
||||
}).compose { RxUtils.toSimpleSingle(it) } |
||||
} |
||||
|
||||
fun bindEmail(user: User, code: String, keyc: String): Single<Result> { |
||||
return Single.create(SingleOnSubscribe<Result> { |
||||
val mediaType = MediaType.parse("application/x-www-form-urlencoded") |
||||
val body = "username=${user.userName}" + |
||||
"&email=${user.email}" + |
||||
"&code=${code}" + |
||||
"&keyc=${keyc}" + |
||||
makeAuth() |
||||
val requestBody = RequestBody.create(mediaType, body) |
||||
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/bindEmail", requestBody, "UTF-8") |
||||
it.onSuccess(GSON.fromJson(ret, Result::class.java)) |
||||
}).compose { RxUtils.toSimpleSingle(it) } |
||||
} |
||||
|
||||
fun resetPwd(user: User, code: String, keyc: String): Single<Result> { |
||||
return Single.create(SingleOnSubscribe<Result> { |
||||
val mediaType = MediaType.parse("application/x-www-form-urlencoded") |
||||
val body = "email=${user.email}" + |
||||
"&password=${user.password}" + |
||||
"&code=${code}" + |
||||
"&keyc=${keyc}" + |
||||
makeAuth() |
||||
val requestBody = RequestBody.create(mediaType, body) |
||||
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/resetPwd", requestBody, "UTF-8") |
||||
it.onSuccess(GSON.fromJson(ret, Result::class.java)) |
||||
}).compose { RxUtils.toSimpleSingle(it) } |
||||
} |
||||
|
||||
fun sendEmail(email: String, type: String, keyc: String = ""): Single<Result> { |
||||
return Single.create(SingleOnSubscribe<Result> { |
||||
val mediaType = MediaType.parse("application/x-www-form-urlencoded") |
||||
val body = "email=${email}" + |
||||
"&type=${type}" + |
||||
"&keyc=${keyc}" + |
||||
makeAuth() |
||||
val requestBody = RequestBody.create(mediaType, body) |
||||
val ret = OkHttpUtils.getHtml(URLCONST.USER_URL + "/do/sendEmail", requestBody, "UTF-8") |
||||
it.onSuccess(GSON.fromJson(ret, Result::class.java)) |
||||
}).compose { RxUtils.toSimpleSingle(it) } |
||||
} |
||||
|
||||
fun webBackup(user: User): Single<Result> { |
||||
return Single.create(SingleOnSubscribe<Result> { |
||||
Backup.backup(App.getmContext(), APPCONST.FILE_DIR + "webBackup/", |
||||
object : Backup.CallBack { |
||||
override fun backupSuccess() { |
||||
val inputFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup") |
||||
val zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip") |
||||
//压缩文件 |
||||
ZipUtils.zipFile(inputFile, zipFile) |
||||
val ret = OkHttpUtils.upload( |
||||
URLCONST.USER_URL + "/do/bak?" + |
||||
"username=${user.userName}" + |
||||
makeAuth(), |
||||
zipFile.absolutePath, |
||||
zipFile.name |
||||
) |
||||
zipFile.delete() |
||||
it.onSuccess(GSON.fromJson(ret, Result::class.java)) |
||||
} |
||||
|
||||
override fun backupError(msg: String) { |
||||
it.onError(Throwable(msg)) |
||||
} |
||||
|
||||
}) |
||||
}).compose { RxUtils.toSimpleSingle(it) } |
||||
} |
||||
|
||||
fun webRestore(user: User): Single<Result> { |
||||
return Single.create(SingleOnSubscribe<Result> { |
||||
val zipFile = FileUtils.getFile(APPCONST.FILE_DIR + "webBackup.zip") |
||||
val input = OkHttpUtils.getInputStream( |
||||
URLCONST.USER_URL + "/do/ret?" + |
||||
"username=${user.userName}" + |
||||
makeAuth() |
||||
) |
||||
if (FileUtils.writeFile(input.readBytes(), zipFile)) { |
||||
ZipUtils.unzipFile(zipFile.absolutePath, APPCONST.FILE_DIR) |
||||
restore(APPCONST.FILE_DIR + "webBackup/", object : Restore.CallBack { |
||||
override fun restoreSuccess() { |
||||
zipFile.delete() |
||||
it.onSuccess(Result(100, "成功从网络同步到本地")) |
||||
} |
||||
|
||||
override fun restoreError(msg: String) { |
||||
it.onError(Throwable(msg)) |
||||
} |
||||
}) |
||||
} |
||||
}).compose { RxUtils.toSimpleSingle(it) } |
||||
} |
||||
|
||||
fun writeConfig(user: User) { |
||||
FileUtils.write(App.getmContext(), "userConfig.fy", GSON.toJson(user)) |
||||
} |
||||
|
||||
fun readConfig(): User? { |
||||
val config = FileUtils.read(App.getmContext(), "userConfig.fy") |
||||
if ("" != config) { |
||||
return GSON.fromJson(config, User::class.java) |
||||
} |
||||
return null |
||||
} |
||||
|
||||
fun writeUsername(username: String) { |
||||
FileUtils.writeText(username, FileUtils.getFile(APPCONST.QQ_DATA_DIR + "user")) |
||||
} |
||||
|
||||
fun readUsername(): String { |
||||
return FileUtils.readText(APPCONST.QQ_DATA_DIR + "user") |
||||
} |
||||
|
||||
private fun makeAuth(): String { |
||||
return "&signal=" + AppInfoUtils.getSingInfo( |
||||
App.getmContext(), |
||||
App.getApplication().packageName, AppInfoUtils.SHA1 |
||||
) + "&appVersion=" + App.getVersionCode() |
||||
} |
||||
} |
@ -0,0 +1,225 @@ |
||||
package xyz.fycz.myreader.ui.activity |
||||
|
||||
import android.app.Activity |
||||
import android.content.Intent |
||||
import android.os.Bundle |
||||
import android.text.Editable |
||||
import android.view.View |
||||
import androidx.appcompat.widget.Toolbar |
||||
import io.reactivex.SingleObserver |
||||
import io.reactivex.disposables.Disposable |
||||
import xyz.fycz.myreader.R |
||||
import xyz.fycz.myreader.application.App |
||||
import xyz.fycz.myreader.base.BaseActivity |
||||
import xyz.fycz.myreader.base.BitIntentDataManager |
||||
import xyz.fycz.myreader.base.MyTextWatcher |
||||
import xyz.fycz.myreader.base.observer.MySingleObserver |
||||
import xyz.fycz.myreader.common.APPCONST |
||||
import xyz.fycz.myreader.databinding.ActivityAuthEmailBinding |
||||
import xyz.fycz.myreader.model.user.Result |
||||
import xyz.fycz.myreader.model.user.User |
||||
import xyz.fycz.myreader.model.user.UserService2 |
||||
import xyz.fycz.myreader.model.user.UserService2.bindEmail |
||||
import xyz.fycz.myreader.model.user.UserService2.register |
||||
import xyz.fycz.myreader.model.user.UserService2.resetPwd |
||||
import xyz.fycz.myreader.model.user.UserService2.sendEmail |
||||
import xyz.fycz.myreader.model.user.UserService2.writeUsername |
||||
import xyz.fycz.myreader.ui.dialog.DialogCreator |
||||
import xyz.fycz.myreader.ui.dialog.LoadingDialog |
||||
import xyz.fycz.myreader.util.CyptoUtils |
||||
import xyz.fycz.myreader.util.ToastUtils |
||||
import java.util.* |
||||
|
||||
/** |
||||
* @author fengyue |
||||
* @date 2021/12/9 15:20 |
||||
*/ |
||||
class AuthEmailActivity : BaseActivity(), SingleObserver<Result> { |
||||
|
||||
private lateinit var binding: ActivityAuthEmailBinding |
||||
private var email = "" |
||||
private var password = "" |
||||
private var emailCode = "" |
||||
private var keyc = "" |
||||
private lateinit var dialog: LoadingDialog |
||||
private var disp: Disposable? = null |
||||
private lateinit var operator: String |
||||
private var user: User? = null |
||||
private var isBind: Boolean = false |
||||
override fun bindView() { |
||||
binding = ActivityAuthEmailBinding.inflate(layoutInflater) |
||||
setContentView(binding.root) |
||||
} |
||||
|
||||
override fun initData(savedInstanceState: Bundle?) { |
||||
user = BitIntentDataManager.getInstance().getData(intent) as User? |
||||
isBind = user != null |
||||
operator = if (isBind) "绑定邮箱" else "重置密码" |
||||
dialog = LoadingDialog(this, "正在请求") { |
||||
disp?.dispose() |
||||
} |
||||
} |
||||
|
||||
override fun setUpToolbar(toolbar: Toolbar?) { |
||||
super.setUpToolbar(toolbar) |
||||
setStatusBarColor(R.color.colorPrimary, true) |
||||
supportActionBar?.title = operator |
||||
} |
||||
|
||||
override fun initWidget() { |
||||
binding.tvTitle.text = operator |
||||
binding.btSubmit.text = operator |
||||
binding.etEmail.editText?.addTextChangedListener(object : MyTextWatcher() { |
||||
override fun afterTextChanged(s: Editable) { |
||||
email = s.toString() |
||||
if (!email.matches("^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,})$".toRegex())) { |
||||
showTip("邮箱格式错误") |
||||
} else { |
||||
binding.tvRegisterTip.visibility = View.GONE |
||||
} |
||||
checkNotNone() |
||||
} |
||||
}) |
||||
|
||||
binding.etEmailCode.editText?.addTextChangedListener(object : MyTextWatcher() { |
||||
override fun afterTextChanged(s: Editable) { |
||||
emailCode = s.toString().trim() |
||||
checkNotNone() |
||||
} |
||||
}) |
||||
binding.etPassword.editText!!.addTextChangedListener(object : MyTextWatcher() { |
||||
override fun afterTextChanged(s: Editable) { |
||||
password = s.toString() |
||||
if (password.length < 8 || password.length > 16) { |
||||
showTip("密码必须在8-16位之间") |
||||
} else if (password.matches("^\\d+$".toRegex())) { |
||||
showTip("密码不能是纯数字") |
||||
} else { |
||||
binding.tvRegisterTip.visibility = View.GONE |
||||
} |
||||
checkNotNone() |
||||
} |
||||
}) |
||||
if (!isBind) { |
||||
binding.etPassword.visibility = View.VISIBLE |
||||
} |
||||
} |
||||
|
||||
override fun initClick() { |
||||
binding.tvGetEmailCode.setOnClickListener { |
||||
if (!email.matches("^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,})$".toRegex())) { |
||||
ToastUtils.showWarring("请正确输入邮箱") |
||||
return@setOnClickListener |
||||
} |
||||
dialog.show() |
||||
dialog.setmMessage("正在发送") |
||||
sendEmail(email, if (isBind) "bind" else "auth", keyc) |
||||
.subscribe(object : MySingleObserver<Result?>() { |
||||
override fun onSubscribe(d: Disposable) { |
||||
addDisposable(d) |
||||
disp = d |
||||
} |
||||
|
||||
override fun onSuccess(result: Result) { |
||||
if (result.code == 106) { |
||||
ToastUtils.showSuccess("验证码发送成功") |
||||
keyc = result.result.toString() |
||||
timeDown(60) |
||||
} else { |
||||
ToastUtils.showWarring(result.result.toString()) |
||||
} |
||||
dialog.dismiss() |
||||
} |
||||
|
||||
override fun onError(e: Throwable) { |
||||
ToastUtils.showError("验证码发送失败:${e.localizedMessage}") |
||||
dialog.dismiss() |
||||
} |
||||
}) |
||||
} |
||||
|
||||
binding.btSubmit.setOnClickListener { |
||||
if (!isBind && (password.matches("^\\d+$".toRegex()) || !password.matches("^.{8,16}$".toRegex()))) { |
||||
DialogCreator.createTipDialog( |
||||
this, "密码格式错误", |
||||
"密码必须在8-16位之间\n密码不能是纯数字" |
||||
) |
||||
} else if (!email.matches("^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,})$".toRegex())) { |
||||
DialogCreator.createTipDialog( |
||||
this, "邮箱格式错误", |
||||
"电子邮箱的正确写法为:用户名@邮箱网站.com(.cn等)" |
||||
) |
||||
} else if ("" == keyc) { |
||||
DialogCreator.createTipDialog(this, "请先获取邮箱验证码") |
||||
} else if (emailCode.length < 6) { |
||||
DialogCreator.createTipDialog(this, "请输入6位邮箱验证码") |
||||
} else { |
||||
dialog.show() |
||||
dialog.setmMessage("正在请求") |
||||
if (isBind) { |
||||
val user = User().apply { |
||||
email = this@AuthEmailActivity.email |
||||
userName = this@AuthEmailActivity.user?.userName |
||||
} |
||||
bindEmail(user, emailCode, keyc) |
||||
.subscribe(this) |
||||
} else { |
||||
val user = User().apply { |
||||
email = this@AuthEmailActivity.email |
||||
password = CyptoUtils.encode(APPCONST.KEY, this@AuthEmailActivity.password) |
||||
} |
||||
resetPwd(user, emailCode, keyc) |
||||
.subscribe(this) |
||||
} |
||||
|
||||
} |
||||
} |
||||
} |
||||
|
||||
fun showTip(tip: String?) { |
||||
binding.tvRegisterTip.visibility = View.VISIBLE |
||||
binding.tvRegisterTip.text = tip |
||||
} |
||||
|
||||
private fun timeDown(time: Int) { |
||||
if (time == 0) { |
||||
binding.tvGetEmailCode.text = getString(R.string.re_get_email_code, "") |
||||
binding.tvGetEmailCode.isEnabled = true |
||||
} else { |
||||
binding.tvGetEmailCode.isEnabled = false |
||||
val timeStr = "($time)" |
||||
binding.tvGetEmailCode.text = getString(R.string.re_get_email_code, timeStr) |
||||
App.getHandler().postDelayed({ timeDown(time - 1) }, 1000) |
||||
} |
||||
} |
||||
|
||||
fun checkNotNone() { |
||||
binding.btSubmit.isEnabled = "" != email && "" != emailCode && (isBind || "" != password) |
||||
} |
||||
|
||||
override fun onDestroy() { |
||||
dialog.dismiss() |
||||
super.onDestroy() |
||||
} |
||||
|
||||
override fun onSubscribe(d: Disposable) { |
||||
addDisposable(d) |
||||
disp = d |
||||
} |
||||
|
||||
override fun onSuccess(result: Result) { |
||||
if (result.code < 200) { |
||||
ToastUtils.showSuccess(result.result.toString()) |
||||
setResult(Activity.RESULT_OK) |
||||
finish() |
||||
} else { |
||||
ToastUtils.showWarring(result.result.toString()) |
||||
} |
||||
dialog.dismiss() |
||||
} |
||||
|
||||
override fun onError(e: Throwable) { |
||||
ToastUtils.showError("失败:${e.localizedMessage}") |
||||
dialog.dismiss() |
||||
} |
||||
} |
@ -0,0 +1,5 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android"> |
||||
<item android:color="@color/textSecondary" android:state_enabled="false" /> |
||||
<item android:color="@color/sys_color"/> |
||||
</selector> |
Before Width: | Height: | Size: 134 KiB |
@ -0,0 +1,125 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:fitsSystemWindows="true" |
||||
android:orientation="vertical"> |
||||
|
||||
<include layout="@layout/toolbar" /> |
||||
|
||||
|
||||
<!--添加标题和输入框--> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="10dp" |
||||
android:orientation="vertical" |
||||
android:padding="10dp"> |
||||
|
||||
<!--标题--> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_title" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/text_register" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/textPrimary" |
||||
android:textSize="@dimen/text_senior_size" /> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_register_tip" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="10dp" |
||||
android:text="" |
||||
android:textColor="@color/textError" |
||||
android:visibility="gone" /> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_email" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="100"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_email" |
||||
android:inputType="text" /> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_password" |
||||
android:visibility="gone" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="16" |
||||
app:passwordToggleEnabled="true" |
||||
app:passwordToggleTintMode="src_in"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_new_password_tip" |
||||
android:inputType="textPassword" /> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal"> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_email_code" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="6"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_email_captcha" |
||||
android:inputType="text" /> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_get_email_code" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:layout_weight="2.5" |
||||
android:gravity="center" |
||||
android:text="@string/get_email_code" |
||||
android:textColor="@color/selector_get_emali_code" |
||||
android:textSize="@dimen/text_small_size" /> |
||||
|
||||
</LinearLayout> |
||||
|
||||
<!--登录按钮--> |
||||
<Button |
||||
android:id="@+id/bt_submit" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="50dp" |
||||
android:layout_marginTop="10dp" |
||||
android:background="@drawable/login_btn_selector" |
||||
android:enabled="false" |
||||
android:text="@string/text_register" |
||||
android:textAlignment="center" |
||||
android:textColor="#ffffff" |
||||
android:textSize="@dimen/text_large_size" /> |
||||
|
||||
</LinearLayout> |
||||
|
||||
</LinearLayout> |
@ -1,241 +1,133 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||
xmlns:tools="http://schemas.android.com/tools" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:background="@color/colorBackground" |
||||
android:fitsSystemWindows="true" |
||||
android:orientation="vertical"> |
||||
|
||||
<include layout="@layout/toolbar" /> |
||||
|
||||
<RelativeLayout |
||||
<!--添加标题和输入框--> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent"> |
||||
<!--背景图片--> |
||||
<ImageView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
android:scaleType="fitXY" |
||||
app:srcCompat="@drawable/bg_login" /> |
||||
<!--添加虚化层--> |
||||
<io.alterac.blurkit.BlurLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="match_parent" |
||||
app:blk_blurRadius="5" |
||||
app:blk_fps="0" /> |
||||
|
||||
<!-- 猫头鹰--> |
||||
<!-- <RelativeLayout--> |
||||
<!-- android:layout_width="300dp"--> |
||||
<!-- android:layout_height="200dp"--> |
||||
<!-- android:layout_centerHorizontal="true"--> |
||||
<!-- android:layout_alignTop="@+id/bg"--> |
||||
<!-- android:layout_marginTop="-75dp">--> |
||||
|
||||
<!-- <!–头像–>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_head"--> |
||||
<!-- android:layout_width="wrap_content"--> |
||||
<!-- android:layout_height="wrap_content"--> |
||||
<!-- android:src="@drawable/owl_head"--> |
||||
<!-- android:layout_centerHorizontal="true"--> |
||||
<!-- />--> |
||||
|
||||
<!-- <!–手掌–>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_left_hand"--> |
||||
<!-- android:layout_width="50dp"--> |
||||
<!-- android:layout_height="60dp"--> |
||||
<!-- android:src="@drawable/icon_hand"--> |
||||
<!-- android:layout_alignParentLeft="true"--> |
||||
<!-- android:layout_alignBottom="@+id/iv_head"--> |
||||
<!-- android:layout_marginBottom="-25dp"--> |
||||
<!-- android:layout_marginLeft="10dp"/>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_right_hand"--> |
||||
<!-- android:layout_width="50dp"--> |
||||
<!-- android:layout_height="60dp"--> |
||||
<!-- android:src="@drawable/icon_hand"--> |
||||
<!-- android:layout_alignParentRight="true"--> |
||||
<!-- android:layout_alignBottom="@+id/iv_head"--> |
||||
<!-- android:layout_marginBottom="-25dp"--> |
||||
<!-- android:layout_marginRight="10dp"/>--> |
||||
|
||||
<!-- <!–翅膀–>--> |
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_left_arm"--> |
||||
<!-- android:layout_width="65dp"--> |
||||
<!-- android:layout_height="40dp"--> |
||||
<!-- android:src="@drawable/arm_left"--> |
||||
<!-- android:layout_below="@+id/iv_head"--> |
||||
<!-- android:layout_alignParentLeft="true"--> |
||||
<!-- android:layout_marginLeft="20dp"/>--> |
||||
|
||||
<!-- <ImageView--> |
||||
<!-- android:id="@+id/iv_right_arm"--> |
||||
<!-- android:layout_width="65dp"--> |
||||
<!-- android:layout_height="40dp"--> |
||||
<!-- android:src="@drawable/arm_right"--> |
||||
<!-- android:layout_below="@+id/iv_head"--> |
||||
<!-- android:layout_alignParentRight="true"--> |
||||
<!-- android:layout_marginRight="20dp"/>--> |
||||
<!-- </RelativeLayout>--> |
||||
|
||||
<View |
||||
android:id="@+id/bg" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="280dp" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
android:background="@drawable/input_bg_shape" /> |
||||
android:layout_height="wrap_content" |
||||
android:layout_margin="10dp" |
||||
android:orientation="vertical" |
||||
android:padding="10dp"> |
||||
|
||||
<io.alterac.blurkit.BlurLayout |
||||
<!--标题--> |
||||
<TextView |
||||
android:layout_width="match_parent" |
||||
android:layout_height="280dp" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
app:blk_blurRadius="20" |
||||
app:blk_fps="0" /> |
||||
|
||||
<!--添加标题和输入框--> |
||||
<LinearLayout |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/text_login" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/textPrimary" |
||||
android:textSize="@dimen/text_senior_size" /> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_user" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_centerInParent="true" |
||||
android:layout_marginLeft="20dp" |
||||
android:layout_marginRight="20dp" |
||||
android:orientation="vertical" |
||||
android:padding="20dp"> |
||||
android:layout_marginTop="20dp" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="14"> |
||||
|
||||
<!--标题--> |
||||
<TextView |
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:text="@string/text_login" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/textSecondary" |
||||
android:textSize="20dp" /> |
||||
|
||||
<!--添加输入框--> |
||||
<!--<EditText |
||||
android:id="@+id/et_user" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="50dp" |
||||
android:background="@drawable/editview_shape" |
||||
android:drawableStart="@drawable/iconfont_user" |
||||
android:drawablePadding="10dp" |
||||
android:hint="@string/et_account_tip" |
||||
android:inputType="text" |
||||
android:maxLines="1" |
||||
android:paddingStart="10dp" |
||||
android:textSize="18dp" />--> |
||||
android:inputType="text" /> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_user" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="20dp" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="14"> |
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_account_tip" |
||||
android:inputType="text"/> |
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_password" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="16" |
||||
app:passwordToggleEnabled="true" |
||||
app:passwordToggleTintMode="src_in"> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
<!--<EditText |
||||
android:id="@+id/et_password" |
||||
style="@style/EditTextStyle" |
||||
android:background="@drawable/editview_shape" |
||||
android:drawableStart="@drawable/iconfont_password" |
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_password_tip" |
||||
android:inputType="textPassword" |
||||
android:textSize="18dp" />--> |
||||
android:inputType="textPassword" /> |
||||
|
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_password" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="16" |
||||
app:passwordToggleEnabled="true" |
||||
app:passwordToggleTintMode="src_in"> |
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_password_tip" |
||||
android:inputType="textPassword"/> |
||||
<LinearLayout |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal"> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
<LinearLayout |
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_captcha" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:orientation="horizontal"> |
||||
android:layout_weight="1" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="4"> |
||||
|
||||
<!--<EditText |
||||
android:id="@+id/et_captcha" |
||||
style="@style/EditTextStyle" |
||||
android:layout_width="match_parent" |
||||
android:layout_weight="1" |
||||
android:background="@drawable/editview_shape" |
||||
android:hint="@string/et_rp_captcha" |
||||
android:inputType="text" |
||||
android:textSize="18dp" />--> |
||||
<com.google.android.material.textfield.TextInputLayout |
||||
android:id="@+id/et_captcha" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="1" |
||||
android:drawablePadding="10dp" |
||||
app:counterEnabled="true" |
||||
app:counterMaxLength="4"> |
||||
|
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:hint="@string/et_rp_captcha" |
||||
android:inputType="text"/> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<ImageView |
||||
android:id="@+id/iv_captcha" |
||||
<com.google.android.material.textfield.TextInputEditText |
||||
android:layout_width="match_parent" |
||||
android:layout_height="wrap_content" |
||||
android:layout_weight="3" |
||||
android:layout_gravity="center_vertical" |
||||
android:paddingStart="7dp" /> |
||||
|
||||
</LinearLayout> |
||||
<!--登录按钮--> |
||||
<Button |
||||
android:id="@+id/bt_login" |
||||
android:hint="@string/et_rp_captcha" |
||||
android:inputType="text" /> |
||||
|
||||
</com.google.android.material.textfield.TextInputLayout> |
||||
|
||||
<ImageView |
||||
android:id="@+id/iv_captcha" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="50dp" |
||||
android:layout_marginTop="20dp" |
||||
android:background="@drawable/login_btn_selector" |
||||
android:enabled="false" |
||||
android:text="@string/text_login" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/textPrimaryInverted" |
||||
android:textSize="25dp" /> |
||||
android:layout_height="wrap_content" |
||||
android:layout_gravity="center_vertical" |
||||
android:layout_weight="2" |
||||
android:paddingStart="7dp" |
||||
tools:ignore="RtlSymmetry" /> |
||||
|
||||
</LinearLayout> |
||||
<!--登录按钮--> |
||||
<Button |
||||
android:id="@+id/bt_login" |
||||
android:layout_width="match_parent" |
||||
android:layout_height="45dp" |
||||
android:layout_marginTop="20dp" |
||||
android:background="@drawable/login_btn_selector" |
||||
android:enabled="false" |
||||
android:text="@string/text_login" |
||||
android:textAlignment="center" |
||||
android:textColor="@color/textPrimaryInverted" |
||||
android:textSize="@dimen/text_large_size" /> |
||||
|
||||
<RelativeLayout |
||||
android:layout_width="match_parent" |
||||
|
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="10dp"> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_register" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_marginTop="10dp" |
||||
android:text="@string/tv_register" |
||||
android:textColor="@color/colorAccent" /> |
||||
</LinearLayout> |
||||
</RelativeLayout> |
||||
|
||||
<TextView |
||||
android:id="@+id/tv_forgot_pwd" |
||||
android:layout_width="wrap_content" |
||||
android:layout_height="wrap_content" |
||||
android:layout_alignParentEnd="true" |
||||
android:text="@string/tv_forget_pwd" |
||||
android:textColor="@color/colorAccent" /> |
||||
</RelativeLayout> |
||||
|
||||
</LinearLayout> |
||||
</LinearLayout> |
@ -1,3 +1,3 @@ |
||||
#Fri Jun 18 21:45:31 CST 2021 |
||||
VERSION_CODE=226 |
||||
VERSION_CODE=227 |
||||
NEED_CREATE_RELEASE=false |
||||
|
Loading…
Reference in new issue