添加加密展示
添加密码对话框 添加输入框显示或隐藏密码。
This commit is contained in:
parent
687ac17419
commit
ff14a8f3ee
@ -1,6 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:theme="@style/Theme.PDFReaderPro"
|
||||||
|
tools:ignore="DiscouragedApi,LockedOrientationActivity,RedundantLabel">
|
||||||
|
|
||||||
<!-- Android 11+ 存储权限 -->
|
<!-- Android 11+ 存储权限 -->
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
@ -32,6 +34,7 @@
|
|||||||
android:name=".ui.act.SplashActivity"
|
android:name=".ui.act.SplashActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/Theme.PDFReaderPro">
|
android:theme="@style/Theme.PDFReaderPro">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
@ -43,12 +46,13 @@
|
|||||||
android:name=".ui.act.MainActivity"
|
android:name=".ui.act.MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/Theme.PDFReaderPro" />
|
android:screenOrientation="portrait" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.act.PdfViewActivity"
|
android:name=".ui.act.PdfViewActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
android:theme="@style/Theme.PDFReaderPro">
|
android:theme="@style/Theme.PDFReaderPro">
|
||||||
<!-- 处理PDF文件打开 -->
|
<!-- 处理PDF文件打开 -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.all.pdfreader.pro.app.ui.adapter
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.all.pdfreader.pro.app.databinding.AdapterPdfItemBinding
|
import com.all.pdfreader.pro.app.databinding.AdapterPdfItemBinding
|
||||||
@ -34,9 +35,16 @@ class PdfAdapter(
|
|||||||
holder.binding.tvFileName.text = item.fileName
|
holder.binding.tvFileName.text = item.fileName
|
||||||
holder.binding.tvFileSize.text = item.fileSize.toFormatFileSize()
|
holder.binding.tvFileSize.text = item.fileSize.toFormatFileSize()
|
||||||
holder.binding.tvFileDate.text = item.lastModified.toSlashDate()
|
holder.binding.tvFileDate.text = item.lastModified.toSlashDate()
|
||||||
Glide.with(holder.binding.root).load(item.thumbnailPath)
|
if (item.isPassword) {
|
||||||
.transform(CenterCrop(), RoundedCorners(8.dpToPx(holder.binding.root.context)))
|
holder.binding.lockLayout.visibility = View.VISIBLE
|
||||||
.into(holder.binding.tvFileImg)
|
holder.binding.tvFileImg.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
holder.binding.lockLayout.visibility = View.GONE
|
||||||
|
holder.binding.tvFileImg.visibility = View.VISIBLE
|
||||||
|
Glide.with(holder.binding.root).load(item.thumbnailPath)
|
||||||
|
.transform(CenterCrop(), RoundedCorners(8.dpToPx(holder.binding.root.context)))
|
||||||
|
.into(holder.binding.tvFileImg)
|
||||||
|
}
|
||||||
|
|
||||||
holder.binding.root.setOnClickListener {
|
holder.binding.root.setOnClickListener {
|
||||||
onItemClick(item)
|
onItemClick(item)
|
||||||
|
|||||||
@ -1,28 +1,15 @@
|
|||||||
package com.all.pdfreader.pro.app.ui.dialog
|
package com.all.pdfreader.pro.app.ui.dialog
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.InputType
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.WindowManager
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import com.all.pdfreader.pro.app.R
|
import com.all.pdfreader.pro.app.R
|
||||||
import com.all.pdfreader.pro.app.databinding.DialogPdfPasswordProtectionBinding
|
import com.all.pdfreader.pro.app.databinding.DialogPdfPasswordProtectionBinding
|
||||||
import com.all.pdfreader.pro.app.databinding.DialogPermissionBinding
|
|
||||||
import com.all.pdfreader.pro.app.databinding.DialogSortBinding
|
|
||||||
import com.all.pdfreader.pro.app.model.SortConfig
|
|
||||||
import com.all.pdfreader.pro.app.model.SortDirection
|
|
||||||
import com.all.pdfreader.pro.app.model.SortField
|
|
||||||
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
|
||||||
import com.all.pdfreader.pro.app.sp.AppStore
|
|
||||||
import com.all.pdfreader.pro.app.ui.act.MainActivity.SortableFragment
|
|
||||||
import com.all.pdfreader.pro.app.ui.view.CustomPasswordTransformation
|
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
|
||||||
import androidx.core.graphics.drawable.toDrawable
|
|
||||||
import com.all.pdfreader.pro.app.util.AppUtils.showKeyboard
|
import com.all.pdfreader.pro.app.util.AppUtils.showKeyboard
|
||||||
import com.all.pdfreader.pro.app.util.FileUtils.isPdfPasswordCorrect
|
import com.all.pdfreader.pro.app.util.FileUtils.isPdfPasswordCorrect
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -34,6 +21,7 @@ class PdfPasswordProtectionDialogFragment(
|
|||||||
) : DialogFragment() {
|
) : DialogFragment() {
|
||||||
|
|
||||||
private lateinit var binding: DialogPdfPasswordProtectionBinding
|
private lateinit var binding: DialogPdfPasswordProtectionBinding
|
||||||
|
var isPasswordVisible = false
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
@ -61,22 +49,41 @@ class PdfPasswordProtectionDialogFragment(
|
|||||||
|
|
||||||
binding.etPassword.showKeyboard()
|
binding.etPassword.showKeyboard()
|
||||||
|
|
||||||
|
|
||||||
binding.tvCancel.setOnClickListener {
|
binding.tvCancel.setOnClickListener {
|
||||||
onCancelClick()
|
onCancelClick()
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
binding.tvConfirm.setOnClickListener {
|
binding.tvConfirm.setOnClickListener {
|
||||||
val password = binding.etPassword.text.toString()
|
val password = binding.etPassword.text.toString()
|
||||||
if(password.isEmpty()){
|
if (password.isEmpty()) {
|
||||||
binding.tilPassword.error = getString(R.string.password_not_empty)
|
binding.tilPassword.error = getString(R.string.password_not_empty)
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
if(isPdfPasswordCorrect(requireActivity(),file,password)){
|
if (isPdfPasswordCorrect(requireActivity(), file, password)) {
|
||||||
onOkClick(password)
|
onOkClick(password)
|
||||||
dismiss()
|
dismiss()
|
||||||
}else{
|
} else {
|
||||||
binding.tilPassword.error = getString(R.string.incorrect_password)
|
binding.tilPassword.error = getString(R.string.incorrect_password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
binding.showPasswordBtn.setOnClickListener {
|
||||||
|
isPasswordVisible = !isPasswordVisible
|
||||||
|
showOrHidePassword(isPasswordVisible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showOrHidePassword(b: Boolean) {
|
||||||
|
if (b) {
|
||||||
|
binding.etPassword.inputType =
|
||||||
|
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||||
|
binding.showPasswordIv.setImageResource(R.drawable.show_password)
|
||||||
|
} else {
|
||||||
|
binding.etPassword.inputType =
|
||||||
|
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
binding.showPasswordIv.setImageResource(R.drawable.hide_password)
|
||||||
|
}
|
||||||
|
// 保持光标在末尾
|
||||||
|
binding.etPassword.setSelection(binding.etPassword.text?.length ?: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,63 +1,88 @@
|
|||||||
package com.all.pdfreader.pro.app.ui.dialog
|
package com.all.pdfreader.pro.app.ui.dialog
|
||||||
|
|
||||||
import android.content.Context
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
|
import android.text.InputType
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.all.pdfreader.pro.app.R
|
||||||
import com.all.pdfreader.pro.app.databinding.DialogPdfSetPasswordBinding
|
import com.all.pdfreader.pro.app.databinding.DialogPdfSetPasswordBinding
|
||||||
|
import com.all.pdfreader.pro.app.util.AppUtils.showKeyboard
|
||||||
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
|
|
||||||
class PdfSetPasswordDialog : DialogFragment() {
|
class PdfSetPasswordDialog(
|
||||||
|
private val onCancelled: () -> Unit, private val onPasswordSet: (String) -> Unit
|
||||||
|
) : DialogFragment(
|
||||||
|
|
||||||
private var _binding: DialogPdfSetPasswordBinding? = null
|
) {
|
||||||
private val binding get() = _binding!!
|
private lateinit var binding: DialogPdfSetPasswordBinding
|
||||||
private var listener: PasswordDialogListener? = null
|
private var isEnterPasswordVisible = false
|
||||||
|
private var isConfirmPasswordVisible = false
|
||||||
interface PasswordDialogListener {
|
|
||||||
fun onPasswordSet(password: String?)
|
|
||||||
fun onPasswordDialogCancelled()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun newInstance(): PdfSetPasswordDialog {
|
|
||||||
return PdfSetPasswordDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
): View? {
|
||||||
_binding = DialogPdfSetPasswordBinding.inflate(inflater, container, false)
|
binding = DialogPdfSetPasswordBinding.inflate(layoutInflater)
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
isCancelable = false
|
||||||
|
dialog?.window?.apply {
|
||||||
|
// 去掉系统默认的背景 padding
|
||||||
|
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
|
||||||
|
// 设置宽度为全屏减去 16dp
|
||||||
|
val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin) // 16dp
|
||||||
|
val width = resources.displayMetrics.widthPixels - margin * 2
|
||||||
|
setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding.etPassword.showKeyboard()
|
||||||
setupListeners()
|
setupListeners()
|
||||||
setupTextWatchers()
|
setupTextWatchers()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupListeners() {
|
private fun setupListeners() {
|
||||||
binding.tvCancel.setOnClickListener {
|
binding.tvCancel.setOnClickListener {
|
||||||
listener?.onPasswordDialogCancelled()
|
onCancelled()
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.tvConfirm.setOnClickListener {
|
binding.tvConfirm.setOnClickListener {
|
||||||
val password = binding.etPassword.text.toString()
|
val password = binding.etPassword.text.toString()
|
||||||
val confirmPassword = binding.etConfirmPassword.text.toString()
|
val confirmPassword = binding.etConfirmPassword.text.toString()
|
||||||
|
|
||||||
if (validatePassword(password, confirmPassword)) {
|
if (validatePassword(password, confirmPassword)) {
|
||||||
listener?.onPasswordSet(password)
|
onPasswordSet(password)
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.enterShowPasswordBtn.setOnClickListener {
|
||||||
|
isEnterPasswordVisible = !isEnterPasswordVisible
|
||||||
|
showOrHidePassword(
|
||||||
|
binding.etPassword,
|
||||||
|
binding.enterShowPasswordIv,
|
||||||
|
isEnterPasswordVisible
|
||||||
|
)
|
||||||
|
}
|
||||||
|
binding.confirmShowPasswordBtn.setOnClickListener {
|
||||||
|
isConfirmPasswordVisible = !isConfirmPasswordVisible
|
||||||
|
showOrHidePassword(
|
||||||
|
binding.etConfirmPassword,
|
||||||
|
binding.confirmShowPasswordIv,
|
||||||
|
isConfirmPasswordVisible
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTextWatchers() {
|
private fun setupTextWatchers() {
|
||||||
@ -86,7 +111,7 @@ class PdfSetPasswordDialog : DialogFragment() {
|
|||||||
binding.tilConfirmPassword.error = null
|
binding.tilConfirmPassword.error = null
|
||||||
|
|
||||||
if (password.isNotEmpty() && confirmPassword.isNotEmpty() && password != confirmPassword) {
|
if (password.isNotEmpty() && confirmPassword.isNotEmpty() && password != confirmPassword) {
|
||||||
binding.tilConfirmPassword.error = "密码不匹配"
|
binding.tilConfirmPassword.error = getString(R.string.password_not_match)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,42 +119,38 @@ class PdfSetPasswordDialog : DialogFragment() {
|
|||||||
binding.tilPassword.error = null
|
binding.tilPassword.error = null
|
||||||
binding.tilConfirmPassword.error = null
|
binding.tilConfirmPassword.error = null
|
||||||
|
|
||||||
// 允许空密码(表示不设置密码)
|
// 不允许空密码
|
||||||
if (password.isEmpty()) {
|
if (password.isEmpty()) {
|
||||||
return true
|
binding.tilPassword.error = getString(R.string.password_not_empty)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 密码长度验证
|
// 密码长度验证
|
||||||
if (password.length < 4) {
|
if (password.length < 4) {
|
||||||
binding.tilPassword.error = "密码长度至少为4位"
|
binding.tilPassword.error = getString(R.string.password_too_short)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 密码匹配验证
|
// 密码匹配验证
|
||||||
if (password != confirmPassword) {
|
if (password != confirmPassword) {
|
||||||
binding.tilConfirmPassword.error = "密码不匹配"
|
binding.tilConfirmPassword.error = getString(R.string.password_not_match)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
private fun showOrHidePassword(inputView: TextInputEditText, imageView: ImageView, b: Boolean) {
|
||||||
super.onAttach(context)
|
if (b) {
|
||||||
if (context is PasswordDialogListener) {
|
inputView.inputType =
|
||||||
listener = context
|
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||||
|
imageView.setImageResource(R.drawable.show_password)
|
||||||
} else {
|
} else {
|
||||||
throw RuntimeException("$context must implement PasswordDialogListener")
|
inputView.inputType =
|
||||||
|
InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
|
||||||
|
imageView.setImageResource(R.drawable.hide_password)
|
||||||
}
|
}
|
||||||
}
|
// 保持光标在末尾
|
||||||
|
inputView.setSelection(inputView.text?.length ?: 0)
|
||||||
override fun onDetach() {
|
|
||||||
super.onDetach()
|
|
||||||
listener = null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,7 +4,6 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
@ -40,9 +39,8 @@ class HomeFrag : BaseFrag(), MainActivity.SortableFragment {
|
|||||||
adapter = PdfAdapter(pdfList = mutableListOf(), onItemClick = { pdf ->
|
adapter = PdfAdapter(pdfList = mutableListOf(), onItemClick = { pdf ->
|
||||||
val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath)
|
val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
|
|
||||||
}, onMoreClick = { pdf ->
|
}, onMoreClick = { pdf ->
|
||||||
Toast.makeText(requireContext(), "更多操作: ${pdf.fileName}", Toast.LENGTH_SHORT).show()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
package com.all.pdfreader.pro.app.ui.view
|
|
||||||
|
|
||||||
import android.text.method.PasswordTransformationMethod
|
|
||||||
import android.view.View
|
|
||||||
|
|
||||||
class CustomPasswordTransformation : PasswordTransformationMethod() {
|
|
||||||
override fun getTransformation(source: CharSequence, view: View): CharSequence {
|
|
||||||
return PasswordCharSequence(source)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PasswordCharSequence(private val mSource: CharSequence) : CharSequence {
|
|
||||||
override val length: Int
|
|
||||||
get() = mSource.length
|
|
||||||
|
|
||||||
override fun get(index: Int): Char {
|
|
||||||
// 最后一位显示原字符,其余显示●
|
|
||||||
return if (index == mSource.length - 1) mSource[index] else '●'
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
|
|
||||||
return mSource.subSequence(startIndex, endIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
7
app/src/main/res/drawable/dr_item_lock_bg.xml
Normal file
7
app/src/main/res/drawable/dr_item_lock_bg.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="8dp"/>
|
||||||
|
<solid android:color="@color/grey"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
9
app/src/main/res/drawable/hide_password.xml
Normal file
9
app/src/main/res/drawable/hide_password.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="366.8dp"
|
||||||
|
android:height="256dp"
|
||||||
|
android:viewportWidth="1467"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M299.1,18.5l917.2,917.2a34.1,34.1 0,0 1,-48.3 48.3L250.9,66.7A34.1,34.1 0,1 1,299.1 18.5zM324.6,188.7l50.6,50.6a918.1,918.1 0,0 0,-113.9 67.5,829.3 829.3,0 0,0 -93.1,75.2l-14.1,13.6c-4.5,4.5 -8.9,8.9 -13.1,13.3l-12,12.9A438.3,438.3 0,0 0,99.7 457.4l-7.3,10.6c-10,15.2 -15.5,27.6 -15.9,35.9 -0.6,15.4 23.2,51.4 64.1,93.3l12.7,12.8c28.7,27.9 64.2,57.8 104.4,85.5 140.2,96.5 308.7,155.6 475.9,155.6 75.1,0 150,-11 222.1,-31.2l54.7,54.7c-85.3,27.7 -178.8,44.7 -276.8,44.7 -256.6,0 -483.8,-126.3 -612.9,-246l-13.2,-12.6c-12.9,-12.6 -24.6,-25 -35.2,-37.1l-10.1,-12a468.4,468.4 0,0 1,-4.8 -5.9l-8.9,-11.7C21.6,557.3 7.3,524.7 8.3,501.2c0.9,-21.5 13.8,-50.7 37,-83.5l8.6,-11.7 9.5,-12 5.1,-6.1 10.7,-12.4 5.6,-6.2 11.9,-12.6 12.6,-12.8c4.4,-4.3 8.8,-8.6 13.4,-12.9l14.1,-12.9c12.1,-10.8 24.9,-21.6 38.4,-32.3l16.6,-12.8a976.1,976.1 0,0 1,132.7 -84.2zM733.6,83c400.6,0 725.3,284.8 725.3,418.1 0,42.4 -32.9,100.2 -90.6,159.2l-12.8,12.7 -6.7,6.3 -13.9,12.7c-4.7,4.2 -9.6,8.4 -14.6,12.6l-15.3,12.6c-5.2,4.2 -10.5,8.3 -16,12.5l-16.6,12.4a929.4,929.4 0,0 1,-125.5 76.1l-51,-50.9a880.5,880.5 0,0 0,112.4 -63.8c58.2,-39 106.9,-82.3 140.3,-123.6 28.1,-34.7 41.9,-64.1 41.9,-78.7 0,-14.6 -13.8,-44 -41.8,-78.7 -33.4,-41.3 -82.1,-84.7 -140.3,-123.6 -136.9,-91.6 -305.5,-147.6 -474.9,-147.6 -74.3,0 -148.5,11.7 -220.2,33.2l-54.1,-54.2c84.4,-29.1 177,-47.2 274.4,-47.2zM536.7,400.8l52,52a152.7,152.7 0,0 0,193.2 193.2l52,52.1a220.9,220.9 0,0 1,-297.2 -297.3zM733.6,280.2a220.9,220.9 0,0 1,196.9 321.3L878.5,549.5a152.7,152.7 0,0 0,-193.2 -193.2L633.2,304.3a220,220 0,0 1,100.4 -24.1z"
|
||||||
|
android:fillColor="#bfbfbf"/>
|
||||||
|
</vector>
|
||||||
12
app/src/main/res/drawable/lock.xml
Normal file
12
app/src/main/res/drawable/lock.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="256dp"
|
||||||
|
android:height="256dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M785.1,416h-61.9v-121.6c0,-108.8 -91.7,-198.4 -202.7,-198.4s-202.7,89.6 -202.7,198.4v121.6h-78.9c-55.5,0 -100.3,44.8 -100.3,100.3v311.5c0,55.5 44.8,100.3 100.3,100.3h546.1c55.5,0 100.3,-44.8 100.3,-100.3L885.3,516.3c0,-55.5 -44.8,-100.3 -100.3,-100.3zM381.9,294.4c0,-74.7 61.9,-134.4 138.7,-134.4s138.7,59.7 138.7,134.4v121.6h-277.3v-121.6zM821.3,827.7c0,19.2 -17.1,36.3 -36.3,36.3L238.9,864c-19.2,0 -36.3,-17.1 -36.3,-36.3L202.7,516.3c0,-19.2 17.1,-36.3 36.3,-36.3h546.1c19.2,0 36.3,17.1 36.3,36.3v311.5z"
|
||||||
|
android:fillColor="#666666"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M512,544c-17.1,0 -32,14.9 -32,32v106.7c0,17.1 14.9,32 32,32s32,-14.9 32,-32v-106.7c0,-17.1 -14.9,-32 -32,-32z"
|
||||||
|
android:fillColor="#666666"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/show_password.xml
Normal file
9
app/src/main/res/drawable/show_password.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="433dp"
|
||||||
|
android:height="256dp"
|
||||||
|
android:viewportWidth="1732"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M872.8,34.5c462.2,0 836.9,328.7 836.9,482.5 0,49 -37.9,115.6 -104.5,183.7l-14.7,14.6 -7.7,7.3 -16,14.6c-5.5,4.9 -11.1,9.7 -16.8,14.6l-17.6,14.5c-6,4.8 -12.2,9.6 -18.4,14.4l-19.2,14.3c-153.2,110.8 -375.1,204.5 -622,204.5 -296,0 -558.2,-145.7 -707.2,-283.9l-15.3,-14.5c-14.8,-14.5 -28.4,-28.8 -40.6,-42.8l-11.7,-13.9a540.4,540.4 0,0 1,-5.5 -6.9l-10.3,-13.5C51.2,581.7 34.8,544.1 35.8,516.9c1,-24.9 16,-58.4 42.7,-96.4l10,-13.5 10.9,-13.9c1.9,-2.4 3.8,-4.7 5.8,-7.1l12.3,-14.3 6.5,-7.2 13.7,-14.6 14.6,-14.7c5,-4.9 10.2,-9.9 15.5,-14.8l16.3,-14.9c13.9,-12.4 28.8,-24.9 44.3,-37.3l19.1,-14.8c152.8,-115.4 375.5,-219.1 625.2,-219.1zM872.8,113.2c-192.4,0 -384.2,67.9 -544.9,179.4a957,957 0,0 0,-107.4 86.7l-16.3,15.6c-5.2,5.2 -10.3,10.3 -15.1,15.4l-13.9,14.9a505.7,505.7 0,0 0,-33.8 41.2l-8.4,12.2c-11.5,17.6 -18,31.9 -18.4,41.5 -0.7,17.7 26.9,59.2 74,107.6l14.7,14.7c33.1,32.2 74,66.6 120.5,98.6 161.8,111.3 356.2,179.6 549.1,179.6 195.5,0 390.1,-64.5 548,-170.2 67.2,-45 123.4,-95 161.9,-142.7 32.3,-40 48.3,-74 48.3,-90.8 0,-16.8 -16,-50.7 -48.2,-90.8 -38.5,-47.7 -94.7,-97.7 -161.9,-142.7 -157.9,-105.7 -352.5,-170.3 -548,-170.3zM872.8,262a254.9,254.9 0,1 1,0 509.9,254.9 254.9,0 0,1 0,-509.9zM872.8,340.8a176.2,176.2 0,1 0,0 352.4,176.2 176.2,0 0,0 0,-352.4z"
|
||||||
|
android:fillColor="#bfbfbf"/>
|
||||||
|
</vector>
|
||||||
12
app/src/main/res/drawable/unlock.xml
Normal file
12
app/src/main/res/drawable/unlock.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="256dp"
|
||||||
|
android:height="256dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M785.1,416L381.9,416v-121.6c0,-74.7 61.9,-134.4 138.7,-134.4 59.7,0 113.1,36.3 132.3,91.7 6.4,17.1 23.5,25.6 40.5,19.2 17.1,-6.4 25.6,-23.5 19.2,-40.5 -27.7,-81.1 -104.5,-134.4 -192,-134.4 -110.9,0 -202.7,89.6 -202.7,198.4v121.6h-78.9c-55.5,0 -100.3,44.8 -100.3,100.3v311.5c0,55.5 44.8,100.3 100.3,100.3h546.1c55.5,0 100.3,-44.8 100.3,-100.3L885.3,516.3c0,-55.5 -44.8,-100.3 -100.3,-100.3zM821.3,827.7c0,19.2 -17.1,36.3 -36.3,36.3L238.9,864c-19.2,0 -36.3,-17.1 -36.3,-36.3L202.7,516.3c0,-19.2 17.1,-36.3 36.3,-36.3h546.1c19.2,0 36.3,17.1 36.3,36.3v311.5z"
|
||||||
|
android:fillColor="#666666"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M512,544c-17.1,0 -32,14.9 -32,32v106.7c0,17.1 14.9,32 32,32s32,-14.9 32,-32v-106.7c0,-17.1 -14.9,-32 -32,-32z"
|
||||||
|
android:fillColor="#666666"/>
|
||||||
|
</vector>
|
||||||
@ -25,6 +25,20 @@
|
|||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
android:src="@mipmap/ic_launcher_round" />
|
android:src="@mipmap/ic_launcher_round" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:visibility="gone"
|
||||||
|
android:id="@+id/lock_layout"
|
||||||
|
android:layout_width="56dp"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:background="@drawable/dr_item_lock_bg"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/lock" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@ -40,11 +54,11 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="middle"
|
android:ellipsize="middle"
|
||||||
|
android:fontFamily="@font/poppins_semibold"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:text="@string/app_name"
|
android:text="@string/app_name"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp" />
|
||||||
android:fontFamily="@font/poppins_semibold"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -57,8 +71,8 @@
|
|||||||
android:id="@+id/tvFileDate"
|
android:id="@+id/tvFileDate"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="2月27,2025"
|
|
||||||
android:fontFamily="@font/poppins_medium"
|
android:fontFamily="@font/poppins_medium"
|
||||||
|
android:text="2月27,2025"
|
||||||
android:textColor="@color/black_60"
|
android:textColor="@color/black_60"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
@ -67,8 +81,8 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:text="8.1MB"
|
|
||||||
android:fontFamily="@font/poppins_medium"
|
android:fontFamily="@font/poppins_medium"
|
||||||
|
android:text="8.1MB"
|
||||||
android:textColor="@color/black_60"
|
android:textColor="@color/black_60"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
|||||||
@ -27,24 +27,46 @@
|
|||||||
android:textColor="@color/black_80"
|
android:textColor="@color/black_80"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<RelativeLayout
|
||||||
android:id="@+id/tilPassword"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp">
|
||||||
android:hint="@string/enter_password"
|
|
||||||
app:endIconMode="password_toggle"
|
|
||||||
app:passwordToggleEnabled="true">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/etPassword"
|
android:id="@+id/tilPassword"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:textSize="16sp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/poppins_regular"
|
android:hint="@string/enter_password"
|
||||||
android:inputType="textPassword" />
|
app:endIconMode="password_toggle"
|
||||||
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/poppins_regular"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/showPasswordBtn"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_alignEnd="@id/tilPassword"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/showPasswordIv"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/hide_password" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@ -27,43 +27,87 @@
|
|||||||
android:textColor="@color/black_60"
|
android:textColor="@color/black_60"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<RelativeLayout
|
||||||
android:id="@+id/tilPassword"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp">
|
||||||
android:hint="@string/enter_password"
|
|
||||||
app:endIconMode="password_toggle"
|
|
||||||
app:passwordToggleEnabled="true">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/etPassword"
|
android:id="@+id/tilPassword"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/poppins_regular"
|
android:hint="@string/enter_password"
|
||||||
android:inputType="textPassword"
|
app:endIconMode="password_toggle"
|
||||||
android:textSize="14sp" />
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/poppins_regular"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
android:id="@+id/tilConfirmPassword"
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/enterShowPasswordBtn"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_alignEnd="@id/tilPassword"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/enterShowPasswordIv"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/hide_password" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp">
|
||||||
android:hint="@string/confirm_password"
|
|
||||||
app:endIconMode="password_toggle"
|
|
||||||
app:passwordToggleEnabled="true">
|
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/etConfirmPassword"
|
android:id="@+id/tilConfirmPassword"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fontFamily="@font/poppins_regular"
|
android:hint="@string/confirm_password"
|
||||||
android:inputType="textPassword"
|
app:endIconMode="password_toggle"
|
||||||
android:textSize="14sp" />
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/etConfirmPassword"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="@font/poppins_regular"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/confirmShowPasswordBtn"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_alignEnd="@id/tilConfirmPassword"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/confirmShowPasswordIv"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@drawable/hide_password" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -79,7 +123,8 @@
|
|||||||
android:fontFamily="@font/poppins_regular"
|
android:fontFamily="@font/poppins_regular"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:text="@string/cancel"
|
android:text="@string/cancel"
|
||||||
android:textColor="@color/black_80" />
|
android:textColor="@color/black_80"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvConfirm"
|
android:id="@+id/tvConfirm"
|
||||||
@ -88,7 +133,8 @@
|
|||||||
android:fontFamily="@font/poppins_medium"
|
android:fontFamily="@font/poppins_medium"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:text="@string/ok"
|
android:text="@string/ok"
|
||||||
android:textColor="@color/black" />
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
<string name="eye_protect">Eye Protect</string>
|
<string name="eye_protect">Eye Protect</string>
|
||||||
<string name="bookmarks">Bookmarks</string>
|
<string name="bookmarks">Bookmarks</string>
|
||||||
<string name="set_pdf_password">Set PDF Password</string>
|
<string name="set_pdf_password">Set PDF Password</string>
|
||||||
<string name="set_pdf_password_dialog_desc">Set a protection password for the PDF file,Leaving it blank means no password is set.</string>
|
<string name="set_pdf_password_dialog_desc">Set a protection password for the PDF file, Leaving it blank means no password is set.</string>
|
||||||
<string name="password_protection">PDF Password Protection</string>
|
<string name="password_protection">PDF Password Protection</string>
|
||||||
<string name="enter_password">Enter password</string>
|
<string name="enter_password">Enter password</string>
|
||||||
<string name="confirm_password">Confirm password</string>
|
<string name="confirm_password">Confirm password</string>
|
||||||
@ -37,4 +37,6 @@
|
|||||||
<string name="password_not_empty">Password cannot be empty</string>
|
<string name="password_not_empty">Password cannot be empty</string>
|
||||||
<string name="incorrect_password">Incorrect password</string>
|
<string name="incorrect_password">Incorrect password</string>
|
||||||
<string name="pdf_loading_failed">PDF loading failed</string>
|
<string name="pdf_loading_failed">PDF loading failed</string>
|
||||||
|
<string name="password_too_short">Password must be at least 4 characters</string>
|
||||||
|
<string name="password_not_match">Passwords do not match</string>
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
Reference in New Issue
Block a user