优化搜索界面,添加工具加密等操作。

This commit is contained in:
ocean 2025-10-10 18:47:32 +08:00
parent 6ffb08dc4f
commit 5bf2952c03
20 changed files with 217 additions and 77 deletions

View File

@ -74,7 +74,7 @@
android:screenOrientation="portrait" />
<activity
android:name=".ui.act.SplitPdfResultActivity"
android:name=".ui.act.PdfResultActivity"
android:exported="true"
android:label="@string/app_name"
android:screenOrientation="portrait" />

View File

@ -4,7 +4,8 @@ enum class PdfPickerSource {
NONE, // 没有任何
MERGE, // PDF合并
SPLIT, // PDF拆分
LOCK, // PDF加密/解密
LOCK, // PDF加密
UNLOCK, // PDF解密
TO_IMAGES, // PDF转图片
TO_LONG_IMAGE // PDF转长图
}

View File

@ -3,5 +3,6 @@ package com.all.pdfreader.pro.app.model
data class PdfSplitResultItem(
val filePath: String,
val thumbnailPath: String? = null,
var isSelected: Boolean
var isSelected: Boolean = false,
var isPassword: Boolean = false
)

View File

@ -62,7 +62,7 @@ class MergePdfActivity : BaseActivity() {
}
binding.continueNowBtn.setOnSingleClickListener {
val list = selectedList.map { it.filePath }
val intent = SplitPdfResultActivity.createIntentInputFile(
val intent = PdfResultActivity.createIntentInputFile(
this, ArrayList(list), PdfPickerSource.MERGE
)
startActivity(intent)

View File

@ -15,6 +15,7 @@ import com.all.pdfreader.pro.app.model.SortConfig
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
import com.all.pdfreader.pro.app.room.repository.PdfRepository
import com.all.pdfreader.pro.app.ui.adapter.PdfAdapter
import com.all.pdfreader.pro.app.ui.dialog.PdfSetPasswordDialog
import com.all.pdfreader.pro.app.util.AppUtils.setClickWithAnimation
import com.all.pdfreader.pro.app.util.AppUtils.setOnSingleClickListener
import com.gyf.immersionbar.ImmersionBar
@ -80,7 +81,21 @@ class PdfPickerActivity : BaseActivity() {
finish()
}
PdfPickerSource.LOCK -> {}
PdfPickerSource.LOCK -> {
PdfSetPasswordDialog(onOkClick = { password ->
val intent = PdfResultActivity.createIntentLock(
this, pdf.filePath, password,
PdfPickerSource.LOCK
)
startActivity(intent)
finish()
}).show(supportFragmentManager, "PdfSetPasswordDialog")
}
PdfPickerSource.UNLOCK -> {
}
PdfPickerSource.TO_IMAGES -> {}
PdfPickerSource.TO_LONG_IMAGE -> {}
PdfPickerSource.NONE -> {}
@ -109,17 +124,25 @@ class PdfPickerActivity : BaseActivity() {
private fun initData() {
lifecycleScope.launch {
PdfRepository.getInstance().getAllDocuments().collect { list ->
if (list.isEmpty()) {
binding.noFilesLayout.visibility = View.VISIBLE
return@collect
}
val sortedList = sortDocuments(list)
// 标记已选择项
if (fromActivityResult == MergePdfActivity.TAG) {
markSelectedItems(sortedList, historyList)
}
if (list.isNotEmpty()) {
adapter.updateData(sortedList)
binding.noFilesLayout.visibility = View.GONE
} else {
binding.noFilesLayout.visibility = View.VISIBLE
// 再根据来源过滤
val displayList = when (source) {
PdfPickerSource.LOCK -> sortedList.filter { !it.isPassword }//只展示没有被加密的
PdfPickerSource.UNLOCK -> sortedList.filter { it.isPassword }//只展示已经被加密的
else -> sortedList
}
adapter.updateData(displayList)
binding.noFilesLayout.visibility =
if (displayList.isEmpty()) View.VISIBLE else View.GONE
}
}
}

View File

@ -1,6 +1,5 @@
package com.all.pdfreader.pro.app.ui.act
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
@ -16,11 +15,13 @@ import com.all.pdfreader.pro.app.databinding.ActivityPdfSplitResultBinding
import com.all.pdfreader.pro.app.model.PdfPickerSource
import com.all.pdfreader.pro.app.model.PdfSelectedPagesItem
import com.all.pdfreader.pro.app.model.PdfSplitResultItem
import com.all.pdfreader.pro.app.ui.adapter.SplitPdfResultAdapter
import com.all.pdfreader.pro.app.room.repository.PdfRepository
import com.all.pdfreader.pro.app.ui.adapter.PdfResultAdapter
import com.all.pdfreader.pro.app.ui.dialog.PromptDialogFragment
import com.all.pdfreader.pro.app.util.AppUtils
import com.all.pdfreader.pro.app.util.FileUtils.toUnderscoreDateTime
import com.all.pdfreader.pro.app.util.PdfScanner
import com.all.pdfreader.pro.app.util.PdfSecurityUtils
import com.all.pdfreader.pro.app.util.PdfUtils
import com.gyf.immersionbar.ImmersionBar
import kotlinx.coroutines.Dispatchers
@ -29,18 +30,20 @@ import kotlinx.coroutines.withContext
import java.io.File
import java.io.Serializable
class SplitPdfResultActivity : BaseActivity() {
override val TAG: String = "SplitPdfResultActivity"
class PdfResultActivity : BaseActivity() {
override val TAG: String = "PdfResultActivity"
companion object {
private const val EXTRA_SELECTED_LIST = "extra_selected_list"
private const val EXTRA_FILE_LIST = "extra_file_list"
private const val EXTRA_SOURCE = "extra_source"
private const val EXTRA_PASSWORD = "extra_password"
private const val EXTRA_FILE_PATH = "extra_file_path"
fun createIntentPdfSelectedPagesItem(
context: Context, list: ArrayList<PdfSelectedPagesItem>, source: PdfPickerSource
): Intent {
return Intent(context, SplitPdfResultActivity::class.java).apply {
return Intent(context, PdfResultActivity::class.java).apply {
putParcelableArrayListExtra(EXTRA_SELECTED_LIST, list)
putExtra(EXTRA_SOURCE, source)
}
@ -49,23 +52,35 @@ class SplitPdfResultActivity : BaseActivity() {
fun createIntentInputFile(
context: Context, list: ArrayList<String>, source: PdfPickerSource
): Intent {
return Intent(context, SplitPdfResultActivity::class.java).apply {
return Intent(context, PdfResultActivity::class.java).apply {
putStringArrayListExtra(EXTRA_FILE_LIST, list)
putExtra(EXTRA_SOURCE, source)
}
}
fun createIntentLock(
context: Context, filepath: String, password: String, source: PdfPickerSource
): Intent {
return Intent(context, PdfResultActivity::class.java).apply {
putExtra(EXTRA_FILE_PATH, filepath)
putExtra(EXTRA_PASSWORD, password)
putExtra(EXTRA_SOURCE, source)
}
}
}
private lateinit var binding: ActivityPdfSplitResultBinding
private lateinit var adapter: SplitPdfResultAdapter
private lateinit var adapter: PdfResultAdapter
private var resultList: MutableList<PdfSplitResultItem> = mutableListOf()
private lateinit var selectedList: ArrayList<PdfSelectedPagesItem>
private lateinit var inputFile: ArrayList<String>
private lateinit var source: PdfPickerSource
private var isSplitting = false
private var isProcessing = false
private var exitDialog: PromptDialogFragment? = null
private val pdfRepository = getRepository()
private lateinit var pdfScanner: PdfScanner
private lateinit var filepath: String
private lateinit var password: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -76,6 +91,8 @@ class SplitPdfResultActivity : BaseActivity() {
.navigationBarColor(R.color.bg_color).init()
selectedList = requireParcelableArrayList(EXTRA_SELECTED_LIST)
inputFile = requireStringArrayList(EXTRA_FILE_LIST)
filepath = intent.getStringExtra(EXTRA_FILE_PATH) ?: ""
password = intent.getStringExtra(EXTRA_PASSWORD) ?: ""
source = getSerializableOrDefault(EXTRA_SOURCE, PdfPickerSource.NONE)
if (source == PdfPickerSource.NONE) {
showToast(getString(R.string.pdf_loading_failed))
@ -94,6 +111,12 @@ class SplitPdfResultActivity : BaseActivity() {
finish()
return
}
} else if (source == PdfPickerSource.LOCK) {
if (filepath.isEmpty() || password.isEmpty()) {
showToast(getString(R.string.pdf_loading_failed))
finish()
return
}
}
}
pdfScanner = PdfScanner(this, pdfRepository)
@ -103,7 +126,7 @@ class SplitPdfResultActivity : BaseActivity() {
}
private fun initView() {
adapter = SplitPdfResultAdapter(resultList)
adapter = PdfResultAdapter(resultList)
binding.recyclerView.layoutManager = LinearLayoutManager(this)
binding.recyclerView.adapter = adapter
}
@ -111,7 +134,7 @@ class SplitPdfResultActivity : BaseActivity() {
private fun initData() {
lifecycleScope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
isSplitting = true
isProcessing = true
binding.processingLayout.visibility = View.VISIBLE
binding.progressBar.isIndeterminate = false
binding.progressBar.progress = 0
@ -143,7 +166,7 @@ class SplitPdfResultActivity : BaseActivity() {
}
})?.let { resultFile ->
val thumbnails =
AppUtils.generateFastThumbnail(this@SplitPdfResultActivity, resultFile)
AppUtils.generateFastThumbnail(this@PdfResultActivity, resultFile)
val result = PdfSplitResultItem(resultFile.absolutePath, thumbnails, false)
pdfScanner.addNewPdfToDatabase(result.filePath, result.thumbnailPath) {
resultList.add(result)
@ -172,13 +195,27 @@ class SplitPdfResultActivity : BaseActivity() {
}
})?.let { resultFile ->
val thumbnails =
AppUtils.generateFastThumbnail(this@SplitPdfResultActivity, resultFile)
AppUtils.generateFastThumbnail(this@PdfResultActivity, resultFile)
val result = PdfSplitResultItem(resultFile.absolutePath, thumbnails, false)
pdfScanner.addNewPdfToDatabase(result.filePath, result.thumbnailPath) {
resultList.add(result)
}
}
}
} else if (source == PdfPickerSource.LOCK) {
binding.congratulationsDesc.text = getString(R.string.set_password_successfully)
PdfSecurityUtils.setPasswordToPdfWithProgress(
filepath, password, password
) { progress ->
binding.progressBar.progress = progress
binding.progressTv.text = "$progress"
}.let { it ->
if (it) {
PdfRepository.getInstance().updateIsPassword(filepath, true)
}
val result = PdfSplitResultItem(filePath = filepath, isPassword = true)
resultList.add(result)
}
}
withContext(Dispatchers.Main) {
binding.processingLayout.visibility = View.GONE
@ -187,7 +224,7 @@ class SplitPdfResultActivity : BaseActivity() {
resultList[0].isSelected = true
}
adapter.updateAdapter()
isSplitting = false//拆分结束
isProcessing = false//拆分结束
exitDialog?.dismissAllowingStateLoss()
exitDialog = null
}
@ -216,12 +253,15 @@ class SplitPdfResultActivity : BaseActivity() {
override fun onDestroy() {
super.onDestroy()
isProcessing = false
exitDialog?.dismissAllowingStateLoss()
exitDialog = null
}
private fun setupBackPressedCallback() {
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (isSplitting) {
if (isProcessing) {
exitDialog = PromptDialogFragment(
getString(R.string.exit_split),
getString(R.string.confirm_discard_changes),

View File

@ -25,6 +25,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.json.JSONArray
import kotlin.math.log
class SearchActivity : BaseActivity() {
override val TAG: String = "SearchActivity"
@ -87,8 +88,9 @@ class SearchActivity : BaseActivity() {
delay(150)
pdfRepository.searchDocuments(query).collectLatest { list ->
if (list.isNotEmpty()) {
adapter.updateData(list)
adapter.updateData(list) {
adapter.highlightItems(query.trim())
}
binding.noFilesLayout.visibility = View.GONE
} else {
adapter.updateData(emptyList())

View File

@ -5,9 +5,7 @@ import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.all.pdfreader.pro.app.R
@ -140,7 +138,7 @@ class SplitPdfActivity : BaseActivity() {
binding.splitBtn.setOnSingleClickListener {
logDebug("${selectedList.size}")
//因为图片做的路径缓存方式所以这里直接传入整个集合到result页处理
val intent = SplitPdfResultActivity.createIntentPdfSelectedPagesItem(
val intent = PdfResultActivity.createIntentPdfSelectedPagesItem(
this,
ArrayList(selectedList),
PdfPickerSource.SPLIT

View File

@ -6,7 +6,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.all.pdfreader.pro.app.R
import com.all.pdfreader.pro.app.databinding.AdapterSplitSelectedResultItemBinding
import com.all.pdfreader.pro.app.databinding.AdapterSelectedResultItemBinding
import com.all.pdfreader.pro.app.model.PdfSplitResultItem
import com.all.pdfreader.pro.app.util.AppUtils.dpToPx
import com.bumptech.glide.Glide
@ -14,15 +14,15 @@ import com.bumptech.glide.load.resource.bitmap.CenterCrop
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import java.io.File
class SplitPdfResultAdapter(
class PdfResultAdapter(
private val list: MutableList<PdfSplitResultItem>
) : RecyclerView.Adapter<SplitPdfResultAdapter.PdfViewHolder>() {
) : RecyclerView.Adapter<PdfResultAdapter.PdfViewHolder>() {
inner class PdfViewHolder(val binding: AdapterSplitSelectedResultItemBinding) :
inner class PdfViewHolder(val binding: AdapterSelectedResultItemBinding) :
RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = PdfViewHolder(
AdapterSplitSelectedResultItemBinding.inflate(
AdapterSelectedResultItemBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
)
@ -35,6 +35,11 @@ class SplitPdfResultAdapter(
.transform(CenterCrop(), RoundedCorners(8.dpToPx(holder.binding.root.context)))
.into(holder.binding.image)
}
if (item.isPassword) {
holder.binding.lockLayout.visibility = View.VISIBLE
} else {
holder.binding.lockLayout.visibility = View.GONE
}
holder.binding.nameTv.text = File(item.filePath).name
holder.binding.pathTv.text =
holder.binding.root.context.getString(R.string.path_details, item.filePath)

View File

@ -1,6 +1,7 @@
package com.all.pdfreader.pro.app.ui.adapter
import android.annotation.SuppressLint
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -24,7 +25,7 @@ class SearchPdfAdapter(
private var showMoreButton: Boolean = true, // 是否显示更多按钮
private var showCheckButton: Boolean = false // 是否显示选择框按钮
) : ListAdapter<PdfDocumentEntity, SearchPdfAdapter.PdfViewHolder>(PdfDiffCallback()) {
private var searchKeyword: String? = null // 保存当前搜索关键字
inner class PdfViewHolder(val binding: AdapterPdfItemBinding) :
RecyclerView.ViewHolder(binding.root)
@ -54,12 +55,13 @@ class SearchPdfAdapter(
holder.binding.checkBtn.visibility = if (showCheckButton) View.VISIBLE else View.GONE
holder.binding.moreBtn.visibility = if (showMoreButton) View.VISIBLE else View.GONE
holder.binding.deleteBtn.visibility = View.GONE
// 文件名高亮,如果 highlightKeyword 为 null 或空字符串,就显示普通文本
holder.binding.tvFileName.text = if (highlightKeyword.isNullOrBlank()) {
val keyword = highlightKeyword ?: searchKeyword
holder.binding.tvFileName.text = if (keyword.isNullOrBlank()) {
item.fileName
} else {
item.fileName.toHighlightedSpannable(highlightKeyword, holder.binding.root.context.getColor(R.color.icon_sel_on_color))
item.fileName.toHighlightedSpannable(keyword, holder.binding.root.context.getColor(R.color.icon_sel_on_color))
}
holder.binding.tvFileSize.text = item.fileSize.toFormatFileSize()
@ -85,14 +87,17 @@ class SearchPdfAdapter(
holder.binding.moreBtn.setOnClickListener { onMoreClick(item) }
}
fun updateData(newList: List<PdfDocumentEntity>) {
submitList(newList.toList())
fun updateData(newList: List<PdfDocumentEntity>, onComplete: (() -> Unit)? = null) {
submitList(newList.toList()) {
onComplete?.invoke()
}
}
/**
* 搜索场景使用只刷新高亮不刷新整个列表
*/
fun highlightItems(keyword: String) {
searchKeyword = keyword
for (i in 0 until itemCount) {
notifyItemChanged(i, keyword)
}

View File

@ -31,7 +31,7 @@ class FileDetailsDialogFragment() : BottomSheetDialogFragment() {
override fun onStart() {
super.onStart()
dialog?.window?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
?.setBackgroundResource(R.drawable.dr_rounded_corner_12_bg_white)
?.setBackgroundResource(R.drawable.dr_rc_top_12_bg_white)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

View File

@ -197,7 +197,9 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
if (pdfDocument.isPassword) {
PdfRemovePasswordDialog().show(parentFragmentManager, "PdfRemovePasswordDialog")
} else {
PdfSetPasswordDialog().show(parentFragmentManager, "PdfSetPasswordDialog")
PdfSetPasswordDialog(onOkClick = { password ->
viewModel.setPassword(pdfDocument.filePath, password)
}).show(parentFragmentManager, "PdfSetPasswordDialog")
}
dismiss()
}

View File

@ -7,24 +7,17 @@ import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import com.all.pdfreader.pro.app.R
import com.all.pdfreader.pro.app.databinding.DialogPdfSetPasswordBinding
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
import com.all.pdfreader.pro.app.util.AppUtils.showKeyboard
import com.all.pdfreader.pro.app.util.ToastUtils
import com.all.pdfreader.pro.app.viewmodel.PdfViewModel
import kotlin.getValue
class PdfSetPasswordDialog() : DialogFragment(
) {
class PdfSetPasswordDialog(
private val onOkClick: (password: String) -> Unit = {}
) : DialogFragment() {
private lateinit var binding: DialogPdfSetPasswordBinding
private val viewModel: PdfViewModel by activityViewModels()
private lateinit var pdfDocument: PdfDocumentEntity
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@ -48,15 +41,9 @@ class PdfSetPasswordDialog() : DialogFragment(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.pdfDocument.value?.let {
pdfDocument = it
binding.etPassword.showKeyboard()
setupListeners()
setupTextWatchers()
} ?: run {
showToast(getString(R.string.file_not))
dismiss()
}
}
private fun setupListeners() {
@ -68,7 +55,7 @@ class PdfSetPasswordDialog() : DialogFragment(
val password = binding.etPassword.text.toString()
val confirmPassword = binding.etConfirmPassword.text.toString()
if (validatePassword(password, confirmPassword)) {
viewModel.setPassword(pdfDocument.filePath, password)
onOkClick(password)
dismiss()
}
}

View File

@ -33,5 +33,9 @@ class ToolsFrag : Fragment() {
val intent = PdfPickerActivity.createIntent(requireActivity(), PdfPickerSource.SPLIT)
startActivity(intent)
}
binding.lockBtn.setOnClickListener {
val intent = PdfPickerActivity.createIntent(requireActivity(), PdfPickerSource.LOCK)
startActivity(intent)
}
}
}

View File

@ -1,23 +1,27 @@
package com.all.pdfreader.pro.app.util
import android.graphics.pdf.PdfDocument
import com.tom_roush.pdfbox.pdmodel.PDDocument
import com.tom_roush.pdfbox.pdmodel.encryption.AccessPermission
import com.tom_roush.pdfbox.pdmodel.encryption.StandardProtectionPolicy
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
object PdfSecurityUtils {
fun setPasswordToPdf(
inputFilePath: String,
userPassword: String,
ownerPassword: String
inputFilePath: String, userPassword: String, ownerPassword: String
): Boolean {
return try {
PDDocument.load(File(inputFilePath)).use { document ->
val accessPermission = AccessPermission()
val protectionPolicy =
StandardProtectionPolicy(ownerPassword, userPassword, accessPermission)
protectionPolicy.encryptionKeyLength = 256
protectionPolicy.encryptionKeyLength = 128
protectionPolicy.permissions = accessPermission
document.protect(protectionPolicy)
document.save(inputFilePath)
@ -29,6 +33,44 @@ object PdfSecurityUtils {
}
}
suspend fun setPasswordToPdfWithProgress(
inputFilePath: String,
userPassword: String,
ownerPassword: String,
onProgress: (Int) -> Unit
): Boolean = withContext(Dispatchers.IO) {
var success = false
// 假进度变量
var progress = 0
val job = launch {
while (isActive && progress < 98) {
delay(50)
// 专业曲线:前 80%慢,后 20%快
progress += when {
progress < 80 -> 1 // 前 80% 每次 +1
progress < 90 -> 2 // 80~90% 每次 +2
else -> 3 // 90~98% 每次 +3
}
if (progress > 98) progress = 98
withContext(Dispatchers.Main) {
onProgress(progress)
}
}
}
success = setPasswordToPdf(inputFilePath, userPassword, ownerPassword)
// 停止假进度
job.cancel()
// 最终完成直接 100%
withContext(Dispatchers.Main) {
onProgress(100)
}
success
}
fun removePasswordFromPdf(inputFilePath: String, password: String): Boolean {
return try {
PDDocument.load(File(inputFilePath), password).use { document ->

View File

@ -109,6 +109,7 @@
android:textSize="20sp" />
<TextView
android:id="@+id/congratulationsDesc"
style="@style/TextViewFont_PopMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -134,7 +135,7 @@
android:layout_height="150dp"
android:layout_margin="16dp"
tools:itemCount="3"
tools:listitem="@layout/adapter_split_selected_result_item" />
tools:listitem="@layout/adapter_selected_result_item" />
<LinearLayout
android:layout_width="match_parent"

View File

@ -49,16 +49,6 @@
android:layout_margin="0.5dp" />
</RelativeLayout>
<ImageView
android:id="@+id/collectState"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:background="@drawable/dr_collect_state_bg"
android:padding="2dp"
android:src="@drawable/collected_white" />
<LinearLayout
android:id="@+id/lock_layout"
android:layout_width="56dp"
@ -73,6 +63,15 @@
android:src="@drawable/lock" />
</LinearLayout>
<ImageView
android:id="@+id/collectState"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignParentEnd="true"
android:background="@drawable/dr_collect_state_bg"
android:padding="2dp"
android:src="@drawable/collected_white" />
</RelativeLayout>
<LinearLayout

View File

@ -37,6 +37,21 @@
android:layout_width="56dp"
android:layout_height="56dp" />
<LinearLayout
android:id="@+id/lock_layout"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="@drawable/dr_item_lock_bg"
android:gravity="center"
android:visibility="gone">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/lock" />
</LinearLayout>
</RelativeLayout>
<LinearLayout

View File

@ -22,4 +22,17 @@
android:layout_height="wrap_content"
android:text="@string/split_pdf" />
<Button
android:id="@+id/lockBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/lock_pdf" />
<Button
android:id="@+id/unLockBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/unlock_pdf" />
</LinearLayout>

View File

@ -29,7 +29,9 @@
<string name="pd_content_notice">Unable to access PDF file, please grant storage permission in settings</string>
<string name="file_not">File does not exist</string>
<string name="lock">Lock</string>
<string name="lock_pdf">Lock PDF</string>
<string name="unlock">Unlock</string>
<string name="unlock_pdf">Unlock PDF</string>
<string name="eye_protect">Eye Protect</string>
<string name="bookmarks">Bookmarks</string>
<string name="no_bookmarks_page">No Bookmarks Page</string>