From 687ac17419021a961fc3bf58a86baf6c8a8398d0 Mon Sep 17 00:00:00 2001 From: ocean <503259349@qq.com> Date: Mon, 8 Sep 2025 15:57:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BE=93=E5=85=A5=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E6=9F=A5=E8=AF=A2pdf?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pro/app/room/entity/PdfDocumentEntity.kt | 1 - .../pro/app/room/repository/PdfRepository.kt | 10 +- .../pro/app/ui/act/PdfViewActivity.kt | 111 ++++-------------- .../PdfPasswordProtectionDialogFragment.kt | 82 +++++++++++++ ...swordDialog.kt => PdfSetPasswordDialog.kt} | 63 +++++----- .../ui/view/CustomPasswordTransformation.kt | 24 ++++ .../all/pdfreader/pro/app/util/AppUtils.kt | 16 +++ .../all/pdfreader/pro/app/util/FileUtils.kt | 17 +++ .../layout/dialog_pdf_password_protection.xml | 76 ++++++++++++ ...ssword.xml => dialog_pdf_set_password.xml} | 61 +++++----- app/src/main/res/values/dimens.xml | 4 + app/src/main/res/values/strings.xml | 9 ++ 12 files changed, 324 insertions(+), 150 deletions(-) create mode 100644 app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfPasswordProtectionDialogFragment.kt rename app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/{PdfPasswordDialog.kt => PdfSetPasswordDialog.kt} (85%) create mode 100644 app/src/main/java/com/all/pdfreader/pro/app/ui/view/CustomPasswordTransformation.kt create mode 100644 app/src/main/res/layout/dialog_pdf_password_protection.xml rename app/src/main/res/layout/{dialog_pdf_password.xml => dialog_pdf_set_password.xml} (59%) create mode 100644 app/src/main/res/values/dimens.xml diff --git a/app/src/main/java/com/all/pdfreader/pro/app/room/entity/PdfDocumentEntity.kt b/app/src/main/java/com/all/pdfreader/pro/app/room/entity/PdfDocumentEntity.kt index 6717fa9..7f81577 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/room/entity/PdfDocumentEntity.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/room/entity/PdfDocumentEntity.kt @@ -3,7 +3,6 @@ package com.all.pdfreader.pro.app.room.entity import android.os.Parcelable import androidx.room.Entity import androidx.room.PrimaryKey -import com.all.pdfreader.pro.app.ui.dialog.PdfPasswordDialog import kotlinx.parcelize.Parcelize @Parcelize diff --git a/app/src/main/java/com/all/pdfreader/pro/app/room/repository/PdfRepository.kt b/app/src/main/java/com/all/pdfreader/pro/app/room/repository/PdfRepository.kt index 91f42bf..3b027dc 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/room/repository/PdfRepository.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/room/repository/PdfRepository.kt @@ -42,7 +42,7 @@ class PdfRepository private constructor(context: Context) { pdfDao.searchDocuments(query) suspend fun updateFavoriteStatus(fileHash: String, isFavorite: Boolean) { - val document = pdfDao.getByHash(fileHash)?.copy( + val document = pdfDao.getByPath(fileHash)?.copy( isFavorite = isFavorite, addedToFavoriteTime = if (isFavorite) System.currentTimeMillis() else null ) @@ -50,7 +50,7 @@ class PdfRepository private constructor(context: Context) { } suspend fun updateReadingProgress(fileHash: String, page: Int, progress: Float) { - val document = pdfDao.getByHash(fileHash)?.copy( + val document = pdfDao.getByPath(fileHash)?.copy( lastOpenedTime = System.currentTimeMillis(), lastReadPage = page, readingProgress = progress @@ -59,14 +59,14 @@ class PdfRepository private constructor(context: Context) { } suspend fun updatePasswordStatus(fileHash: String, isPassword: Boolean) { - val document = pdfDao.getByHash(fileHash)?.copy( + val document = pdfDao.getByPath(fileHash)?.copy( isPassword = isPassword ) document?.let { pdfDao.update(it) } } suspend fun updatePassword(fileHash: String, password: String?) { - val document = pdfDao.getByHash(fileHash)?.copy( + val document = pdfDao.getByPath(fileHash)?.copy( password = password ) document?.let { pdfDao.update(it) } @@ -113,7 +113,7 @@ class PdfRepository private constructor(context: Context) { // 组合查询 suspend fun getPdfWithDetails(pdfHash: String): Flow { return combine( - pdfDao.getByHash(pdfHash)?.let { kotlinx.coroutines.flow.flowOf(it) } + pdfDao.getByPath(pdfHash)?.let { kotlinx.coroutines.flow.flowOf(it) } ?: kotlinx.coroutines.flow.flowOf(null), bookmarkDao.getBookmarksByPdf(pdfHash), noteDao.getNotesByPdf(pdfHash) diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfViewActivity.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfViewActivity.kt index e7bc73e..6e91d34 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfViewActivity.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/act/PdfViewActivity.kt @@ -8,6 +8,7 @@ import androidx.lifecycle.lifecycleScope import com.all.pdfreader.pro.app.R import com.all.pdfreader.pro.app.databinding.ActivityPdfViewBinding import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity +import com.all.pdfreader.pro.app.ui.dialog.PdfPasswordProtectionDialogFragment import com.all.pdfreader.pro.app.ui.view.CustomScrollHandle import com.all.pdfreader.pro.app.viewmodel.PdfViewModel import com.github.barteksc.pdfviewer.listener.OnErrorListener @@ -19,7 +20,7 @@ import java.io.File class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeListener, OnErrorListener { override val TAG: String = "PdfViewActivity" - + companion object { private const val EXTRA_PDF_HASH = "extra_pdf_hash" @@ -63,32 +64,13 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList // 使用传递的文件路径加载PDF val file = File(pdfDocument.filePath) if (file.exists()) { - val pdfView = binding.pdfview - - // 如果有密码,先尝试使用密码加载 - if (!pdfDocument.password.isNullOrEmpty()) { - try { - pdfView.fromFile(file) - .password(pdfDocument.password) // 使用密码加载 - .defaultPage(pdfDocument.lastReadPage) - .enableDoubletap(true) - .onLoad(this) - .enableAnnotationRendering(true) - .onError(this) - .onPageChange(this) - .scrollHandle(CustomScrollHandle(this)) - .load() - return - } catch (e: Exception) { - logDebug("Password protected PDF failed: ${e.message}") - // 密码错误,显示密码输入对话框 - showPasswordDialog(file) - return - } + //需要密码展示对话框。 + if (pdfDocument.isPassword) { + showPasswordDialog(file) + return } - // 无密码PDF正常加载 - pdfView.fromFile(file) + binding.pdfview.fromFile(file) .defaultPage(pdfDocument.lastReadPage) // 从上次阅读页码开始 .enableDoubletap(true)// 是否允许双击缩放 .onLoad(this) @@ -113,22 +95,13 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList logDebug("PDF loading error: ${t?.message}") t?.let { val errorMessage = it.message ?: "未知错误" - // 检查是否是密码相关的错误 if (errorMessage.contains("Password") || errorMessage.contains("password")) { - // 如果当前没有设置密码,显示密码输入对话框 - if (pdfDocument.password.isNullOrEmpty()) { - val file = File(pdfDocument.filePath) - showPasswordDialog(file) - } else { - // 密码错误,显示密码输入对话框 - showToast("PDF密码错误") - val file = File(pdfDocument.filePath) - showPasswordDialog(file) - } + val file = File(pdfDocument.filePath) + showPasswordDialog(file) } else { // 其他错误 - showToast("PDF加载失败: $errorMessage") + showToast(getString(R.string.pdf_loading_failed)) finish() } } @@ -156,57 +129,23 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList } private fun showPasswordDialog(file: File) { - val builder = android.app.AlertDialog.Builder(this) - builder.setTitle("PDF密码保护") - builder.setMessage("请输入PDF文件密码:") - - val input = android.widget.EditText(this) - input.inputType = android.text.InputType.TYPE_CLASS_TEXT or android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD - builder.setView(input) - - builder.setPositiveButton("确定") { dialog, _ -> - val password = input.text.toString() - if (password.isNotEmpty()) { - // 尝试使用输入的密码重新加载PDF - tryLoadPdfWithPassword(file, password) - } else { - showToast("密码不能为空") - } - dialog.dismiss() - } - - builder.setNegativeButton("取消") { dialog, _ -> - dialog.cancel() + PdfPasswordProtectionDialogFragment(file, onOkClick = { password -> + tryLoadPdfWithPassword(file, password) + }, onCancelClick = { finish() - } - - builder.setOnCancelListener { - finish() - } - - builder.show() + }).show(supportFragmentManager, TAG) } - + private fun tryLoadPdfWithPassword(file: File, password: String) { - try { - binding.pdfview.fromFile(file) - .password(password) // 使用输入的密码 - .defaultPage(pdfDocument.lastReadPage) - .enableDoubletap(true) - .onLoad(this) - .enableAnnotationRendering(true) - .onError { error -> - logDebug("Password still incorrect: ${error?.message}") - showToast("密码错误,请重试") - showPasswordDialog(file) // 重新显示密码对话框 - } - .onPageChange(this) - .scrollHandle(CustomScrollHandle(this)) - .load() - } catch (e: Exception) { - logDebug("Failed to load PDF with provided password: ${e.message}") - showToast("密码错误,请重试") - showPasswordDialog(file) // 重新显示密码对话框 - } + binding.pdfview.fromFile(file) + .password(password) // 使用输入的密码 + .defaultPage(pdfDocument.lastReadPage) // 从上次阅读页码开始 + .enableDoubletap(true)// 是否允许双击缩放 + .onLoad(this) + .enableAnnotationRendering(true) // 是否渲染注释(如评论、颜色、表单等) + .onError(this) + .onPageChange(this) + .scrollHandle(CustomScrollHandle(this)) + .load() } } \ No newline at end of file diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfPasswordProtectionDialogFragment.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfPasswordProtectionDialogFragment.kt new file mode 100644 index 0000000..50fbf4f --- /dev/null +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfPasswordProtectionDialogFragment.kt @@ -0,0 +1,82 @@ +package com.all.pdfreader.pro.app.ui.dialog + +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.ColorDrawable +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import android.view.inputmethod.InputMethodManager +import androidx.fragment.app.DialogFragment +import com.all.pdfreader.pro.app.R +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.FileUtils.isPdfPasswordCorrect +import java.io.File + +class PdfPasswordProtectionDialogFragment( + private val file: File, + private val onOkClick: (String) -> Unit, + private val onCancelClick: () -> Unit +) : DialogFragment() { + + private lateinit var binding: DialogPdfPasswordProtectionBinding + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? + ): View? { + binding = DialogPdfPasswordProtectionBinding.inflate(layoutInflater) + 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?) { + super.onViewCreated(view, savedInstanceState) + + binding.etPassword.showKeyboard() + + binding.tvCancel.setOnClickListener { + onCancelClick() + dismiss() + } + binding.tvConfirm.setOnClickListener { + val password = binding.etPassword.text.toString() + if(password.isEmpty()){ + binding.tilPassword.error = getString(R.string.password_not_empty) + return@setOnClickListener + } + if(isPdfPasswordCorrect(requireActivity(),file,password)){ + onOkClick(password) + dismiss() + }else{ + binding.tilPassword.error = getString(R.string.incorrect_password) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfPasswordDialog.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfSetPasswordDialog.kt similarity index 85% rename from app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfPasswordDialog.kt rename to app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfSetPasswordDialog.kt index 294e1ee..c65e88d 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfPasswordDialog.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/PdfSetPasswordDialog.kt @@ -1,6 +1,5 @@ package com.all.pdfreader.pro.app.ui.dialog -import android.app.Dialog import android.content.Context import android.os.Bundle import android.text.Editable @@ -9,54 +8,58 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.DialogFragment -import com.all.pdfreader.pro.app.databinding.DialogPdfPasswordBinding +import com.all.pdfreader.pro.app.databinding.DialogPdfSetPasswordBinding -class PdfPasswordDialog : DialogFragment() { - - private var _binding: DialogPdfPasswordBinding? = null +class PdfSetPasswordDialog : DialogFragment() { + + private var _binding: DialogPdfSetPasswordBinding? = null private val binding get() = _binding!! private var listener: PasswordDialogListener? = null - + interface PasswordDialogListener { fun onPasswordSet(password: String?) fun onPasswordDialogCancelled() } - + companion object { - fun newInstance(): PdfPasswordDialog { - return PdfPasswordDialog() + fun newInstance(): PdfSetPasswordDialog { + return PdfSetPasswordDialog() } } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - _binding = DialogPdfPasswordBinding.inflate(inflater, container, false) + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + _binding = DialogPdfSetPasswordBinding.inflate(inflater, container, false) return binding.root } - + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - + setupListeners() setupTextWatchers() } - + private fun setupListeners() { binding.tvCancel.setOnClickListener { listener?.onPasswordDialogCancelled() dismiss() } - + binding.tvConfirm.setOnClickListener { val password = binding.etPassword.text.toString() val confirmPassword = binding.etConfirmPassword.text.toString() - + if (validatePassword(password, confirmPassword)) { listener?.onPasswordSet(password) dismiss() } } } - + private fun setupTextWatchers() { binding.etPassword.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} @@ -65,7 +68,7 @@ class PdfPasswordDialog : DialogFragment() { validateInput() } }) - + binding.etConfirmPassword.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} @@ -74,43 +77,43 @@ class PdfPasswordDialog : DialogFragment() { } }) } - + private fun validateInput() { val password = binding.etPassword.text.toString() val confirmPassword = binding.etConfirmPassword.text.toString() - + binding.tilPassword.error = null binding.tilConfirmPassword.error = null - + if (password.isNotEmpty() && confirmPassword.isNotEmpty() && password != confirmPassword) { binding.tilConfirmPassword.error = "密码不匹配" } } - + private fun validatePassword(password: String, confirmPassword: String): Boolean { binding.tilPassword.error = null binding.tilConfirmPassword.error = null - + // 允许空密码(表示不设置密码) if (password.isEmpty()) { return true } - + // 密码长度验证 if (password.length < 4) { binding.tilPassword.error = "密码长度至少为4位" return false } - + // 密码匹配验证 if (password != confirmPassword) { binding.tilConfirmPassword.error = "密码不匹配" return false } - + return true } - + override fun onAttach(context: Context) { super.onAttach(context) if (context is PasswordDialogListener) { @@ -119,12 +122,12 @@ class PdfPasswordDialog : DialogFragment() { throw RuntimeException("$context must implement PasswordDialogListener") } } - + override fun onDetach() { super.onDetach() listener = null } - + override fun onDestroyView() { super.onDestroyView() _binding = null diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/view/CustomPasswordTransformation.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/view/CustomPasswordTransformation.kt new file mode 100644 index 0000000..ad12944 --- /dev/null +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/view/CustomPasswordTransformation.kt @@ -0,0 +1,24 @@ +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) + } + } +} diff --git a/app/src/main/java/com/all/pdfreader/pro/app/util/AppUtils.kt b/app/src/main/java/com/all/pdfreader/pro/app/util/AppUtils.kt index dd7df96..fe0dc23 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/util/AppUtils.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/util/AppUtils.kt @@ -1,7 +1,11 @@ package com.all.pdfreader.pro.app.util +import android.app.Activity import android.content.Context import android.view.View +import android.view.WindowManager +import android.view.inputmethod.InputMethodManager +import android.widget.EditText object AppUtils { @@ -42,4 +46,16 @@ object AppUtils { return (this * context.resources.displayMetrics.density).toInt() } + /** + * 软键盘弹出 + */ + fun EditText.showKeyboard() { + requestFocus() + (context as? Activity)?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE) + postDelayed({ + val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) + }, 200) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/all/pdfreader/pro/app/util/FileUtils.kt b/app/src/main/java/com/all/pdfreader/pro/app/util/FileUtils.kt index 41a1cd9..e1c236c 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/util/FileUtils.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/util/FileUtils.kt @@ -8,6 +8,7 @@ import android.os.ParcelFileDescriptor import android.provider.MediaStore import android.provider.OpenableColumns import android.util.Log +import com.shockwave.pdfium.PdfiumCore import java.io.File import java.io.IOException import java.io.InputStream @@ -345,6 +346,22 @@ object FileUtils { } } + /** + * 判断pdf密码是否正确 + */ + fun isPdfPasswordCorrect(context: Context, file: File, password: String): Boolean { + return try { + val descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY) + val pdfiumCore = PdfiumCore(context) + val doc = pdfiumCore.newDocument(descriptor, password) + pdfiumCore.closeDocument(doc) + true // 没抛异常说明密码正确 + } catch (e: Exception) { + false // 抛异常说明密码错误 + } + } + + fun getFileFromUri(context: Context, uri: Uri): File? { // 先尝试通过 DATA 字段获取 val projection = arrayOf(MediaStore.Files.FileColumns.DATA) diff --git a/app/src/main/res/layout/dialog_pdf_password_protection.xml b/app/src/main/res/layout/dialog_pdf_password_protection.xml new file mode 100644 index 0000000..221f2df --- /dev/null +++ b/app/src/main/res/layout/dialog_pdf_password_protection.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_pdf_password.xml b/app/src/main/res/layout/dialog_pdf_set_password.xml similarity index 59% rename from app/src/main/res/layout/dialog_pdf_password.xml rename to app/src/main/res/layout/dialog_pdf_set_password.xml index b910ae1..3797a89 100644 --- a/app/src/main/res/layout/dialog_pdf_password.xml +++ b/app/src/main/res/layout/dialog_pdf_set_password.xml @@ -3,43 +3,46 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" + android:background="@drawable/dr_rounded_corner_12_bg_white" android:orientation="vertical" - android:padding="24dp" - android:background="@android:color/white"> + android:padding="24dp"> + android:layout_marginBottom="16dp" + android:fontFamily="@font/poppins_semibold" + android:text="@string/set_pdf_password" + android:textColor="@color/black" + android:textSize="20sp" /> + android:layout_marginBottom="16dp" + android:fontFamily="@font/poppins_regular" + android:text="@string/set_pdf_password_dialog_desc" + android:textColor="@color/black_60" + android:textSize="14sp" /> + app:passwordToggleEnabled="true"> + android:fontFamily="@font/poppins_regular" + android:inputType="textPassword" + android:textSize="14sp" /> @@ -47,43 +50,45 @@ android:id="@+id/tilConfirmPassword" android:layout_width="match_parent" android:layout_height="wrap_content" - android:hint="确认密码" - app:passwordToggleEnabled="true" + android:layout_marginBottom="24dp" + android:hint="@string/confirm_password" app:endIconMode="password_toggle" - android:layout_marginBottom="24dp"> + app:passwordToggleEnabled="true"> + android:fontFamily="@font/poppins_regular" + android:inputType="textPassword" + android:textSize="14sp" /> + android:gravity="end" + android:orientation="horizontal"> + android:fontFamily="@font/poppins_regular" + android:padding="12dp" + android:text="@string/cancel" + android:textColor="@color/black_80" /> + android:text="@string/ok" + android:textColor="@color/black" /> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..bda39f2 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,4 @@ + + + 16dp + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c505e03..63f9c1c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -28,4 +28,13 @@ Unlock Eye Protect Bookmarks + Set PDF Password + Set a protection password for the PDF file,Leaving it blank means no password is set. + PDF Password Protection + Enter password + Confirm password + Please enter the PDF file password + Password cannot be empty + Incorrect password + PDF loading failed \ No newline at end of file