修复bug:could not find Fragment constructor

This commit is contained in:
ocean 2025-12-03 18:21:16 +08:00
parent edc573d3c4
commit bc5453e85d
23 changed files with 519 additions and 260 deletions

View File

@ -52,7 +52,7 @@ android {
) )
} }
debug { debug {
isMinifyEnabled = true isMinifyEnabled = false
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
) )

View File

@ -1,10 +1,13 @@
package com.all.pdfreader.pdf.reader.room.entity package com.all.pdfreader.pdf.reader.room.entity
import android.os.Parcelable
import androidx.room.Entity import androidx.room.Entity
import androidx.room.ForeignKey import androidx.room.ForeignKey
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
@Parcelize
@Entity( @Entity(
tableName = "bookmarks", tableName = "bookmarks",
foreignKeys = [ForeignKey( foreignKeys = [ForeignKey(
@ -26,4 +29,4 @@ data class BookmarkEntity(
val positionX: Float = 0f, // 页面内X位置 val positionX: Float = 0f, // 页面内X位置
val positionY: Float = 0f, // 页面内Y位置 val positionY: Float = 0f, // 页面内Y位置
val createTime: Long = System.currentTimeMillis() val createTime: Long = System.currentTimeMillis()
) ): Parcelable

View File

@ -272,12 +272,14 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
title = getString(R.string.delete_all_file_title) title = getString(R.string.delete_all_file_title)
desc = getString(R.string.delete_all_file_desc) desc = getString(R.string.delete_all_file_desc)
} }
PromptDialogFragment( val promptDialogFragment = PromptDialogFragment.newInstance(
title, desc, onOkClick = { title = title, desc = desc
viewModel.deleteFiles(filesToDelete) )
exitAllMultiSelect() promptDialogFragment.onOkClick ={
}, onCancelClick = { viewModel.deleteFiles(filesToDelete)
}).show(supportFragmentManager, "deleteFiles") exitAllMultiSelect()
}
promptDialogFragment.show(supportFragmentManager, "deleteFiles")
} }
} }
binding.multiSelectMergeBtn.setOnSingleClickListener { binding.multiSelectMergeBtn.setOnSingleClickListener {
@ -297,14 +299,17 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
val selectedItems = recentlyFragment.adapter.getSelectedItems() val selectedItems = recentlyFragment.adapter.getSelectedItems()
if (selectedItems.isNotEmpty()) { if (selectedItems.isNotEmpty()) {
val filePaths = selectedItems.map { it.filePath } val filePaths = selectedItems.map { it.filePath }
PromptDialogFragment(
getString(R.string.remove_dialog_title), val promptDialogFragment = PromptDialogFragment.newInstance(
getString(R.string.remove_dialog_desc), title = getString(R.string.remove_dialog_title),
getString(R.string.remove), desc = getString(R.string.remove_dialog_desc),
onOkClick = { okBtnText = getString(R.string.remove)
viewModel.removeRecentAll(filePaths) )
exitAllMultiSelect() promptDialogFragment.onOkClick = {
}).show(supportFragmentManager, "removeRecent") viewModel.removeRecentAll(filePaths)
exitAllMultiSelect()
}
promptDialogFragment.show(supportFragmentManager, "removeRecent")
} }
} }
binding.multiSelectUnFavoriteBtn.setOnSingleClickListener { binding.multiSelectUnFavoriteBtn.setOnSingleClickListener {
@ -564,10 +569,12 @@ class MainActivity : BaseActivity(), PermissionDialogFragment.PermissionCallback
private fun setupDoubleBackExit() { private fun setupDoubleBackExit() {
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
ExitDialogFragment(onExitClick = { val exitDialogFragment = ExitDialogFragment()
exitDialogFragment.onExitClick = {
isEnabled = false // 解除拦截 isEnabled = false // 解除拦截
onBackPressedDispatcher.onBackPressed() // 调用系统默认返回逻辑 onBackPressedDispatcher.onBackPressed() // 调用系统默认返回逻辑
}).show(supportFragmentManager, TAG) }
exitDialogFragment.show(supportFragmentManager, TAG)
} }
}) })
} }

View File

@ -89,17 +89,19 @@ class MergePdfActivity : BaseActivity() {
*/ */
private suspend fun showPasswordDialogSuspend(file: File): String? = private suspend fun showPasswordDialogSuspend(file: File): String? =
suspendCancellableCoroutine { cont -> suspendCancellableCoroutine { cont ->
PdfPasswordProtectionDialogFragment( val pdfPasswordProtectionDialogFragment =
file, onOkClick = { password -> PdfPasswordProtectionDialogFragment.newInstance(file.absolutePath, true)
if (cont.isActive) { pdfPasswordProtectionDialogFragment.onCancelClick = {
cont.resumeWith(Result.success(password)) if (cont.isActive) {
} cont.resumeWith(Result.success(null))
}, onCancelClick = { }
if (cont.isActive) { }
cont.resumeWith(Result.success(null)) pdfPasswordProtectionDialogFragment.onOkClick = { password ->
} if (cont.isActive) {
}, isPrompt = true cont.resumeWith(Result.success(password))
).show(supportFragmentManager, TAG) }
}
pdfPasswordProtectionDialogFragment.show(supportFragmentManager, TAG)
} }
private fun initView() { private fun initView() {
@ -171,16 +173,17 @@ class MergePdfActivity : BaseActivity() {
override fun shouldInterceptBackPress(): Boolean = true override fun shouldInterceptBackPress(): Boolean = true
override fun onInterceptBackPressed() { override fun onInterceptBackPressed() {
PromptDialogFragment( val promptDialogFragment = PromptDialogFragment.newInstance(
getString(R.string.exit_merge), title = getString(R.string.exit_merge),
getString(R.string.confirm_discard_changes), desc = getString(R.string.confirm_discard_changes),
getString(R.string.discard), okBtnText = getString(R.string.discard)
onOkClick = { )
backPressedCallback?.isEnabled = false promptDialogFragment.onOkClick = {
onBackPressedDispatcher.onBackPressed() backPressedCallback?.isEnabled = false
AnalyticsUtils.logEvent(AnalyticsUtils.Event.MERGE_BACK_CONFIRM) onBackPressedDispatcher.onBackPressed()
}, onCancelClick = { AnalyticsUtils.logEvent(AnalyticsUtils.Event.MERGE_BACK_CONFIRM)
}).show(supportFragmentManager, getString(R.string.exit_merge)) }
promptDialogFragment.show(supportFragmentManager, getString(R.string.exit_merge))
} }
companion object { companion object {

View File

@ -93,59 +93,81 @@ class PdfPickerActivity : BaseActivity() {
} }
PdfPickerSource.LOCK -> { PdfPickerSource.LOCK -> {
PdfSetPasswordDialog(onOkClick = { password -> val pdfSetPasswordDialog = PdfSetPasswordDialog.newInstance()
pdfSetPasswordDialog.onOkClick = { password ->
val intent = PdfResultActivity.createIntentLock( val intent = PdfResultActivity.createIntentLock(
this, pdf.filePath, password, this, pdf.filePath, password,
PdfPickerSource.LOCK PdfPickerSource.LOCK
) )
startActivity(intent) startActivity(intent)
finish() finish()
}).show(supportFragmentManager, "PdfSetPasswordDialog") }
pdfSetPasswordDialog.show(supportFragmentManager, "PdfSetPasswordDialog")
} }
PdfPickerSource.UNLOCK -> { PdfPickerSource.UNLOCK -> {
PdfRemovePasswordDialog(pdf.filePath, onOkClick = { password -> val pdfRemovePasswordDialog =
PdfRemovePasswordDialog.newInstance(pdf.filePath)
pdfRemovePasswordDialog.onOkClick = { password ->
val intent = PdfResultActivity.createIntentLock( val intent = PdfResultActivity.createIntentLock(
this, pdf.filePath, password, this, pdf.filePath, password,
PdfPickerSource.UNLOCK PdfPickerSource.UNLOCK
) )
startActivity(intent) startActivity(intent)
finish() finish()
}).show(supportFragmentManager, "PdfRemovePasswordDialog") }
pdfRemovePasswordDialog.show(
supportFragmentManager,
"PdfRemovePasswordDialog"
)
} }
PdfPickerSource.IMAGES_TO_PDF -> {} PdfPickerSource.IMAGES_TO_PDF -> {}
PdfPickerSource.TO_LONG_IMAGE -> { PdfPickerSource.TO_LONG_IMAGE -> {
val intent = PdfToImageActivity.createIntent(this, pdf.filePath, val intent = PdfToImageActivity.createIntent(
PdfPickerSource.TO_LONG_IMAGE) this, pdf.filePath,
startActivity(intent) PdfPickerSource.TO_LONG_IMAGE
finish() )
}
PdfPickerSource.NONE -> {}
PdfPickerSource.PDF_TO_IMAGES -> {
val intent = PdfToImageActivity.createIntent(this, pdf.filePath,
PdfPickerSource.PDF_TO_IMAGES)
startActivity(intent) startActivity(intent)
finish() finish()
} }
PdfPickerSource.PRINT ->{ PdfPickerSource.NONE -> {}
PdfPickerSource.PDF_TO_IMAGES -> {
val intent = PdfToImageActivity.createIntent(
this, pdf.filePath,
PdfPickerSource.PDF_TO_IMAGES
)
startActivity(intent)
finish()
}
PdfPickerSource.PRINT -> {
val result = printPdfFile(this, Uri.fromFile(File(pdf.filePath))) val result = printPdfFile(this, Uri.fromFile(File(pdf.filePath)))
when (result) { when (result) {
PrintResult.DeviceNotSupported -> { PrintResult.DeviceNotSupported -> {
ToastUtils.show(this,getString(R.string.device_does_not_support_printing)) ToastUtils.show(
this,
getString(R.string.device_does_not_support_printing)
)
} }
is PrintResult.Error -> { is PrintResult.Error -> {
ToastUtils.show(this,getString(R.string.pdf_cannot_print_error)) ToastUtils.show(this, getString(R.string.pdf_cannot_print_error))
} }
PrintResult.MalformedPdf -> { PrintResult.MalformedPdf -> {
ToastUtils.show(this,getString(R.string.cannot_print_malformed_pdf)) ToastUtils.show(
this,
getString(R.string.cannot_print_malformed_pdf)
)
} }
PrintResult.PasswordRequired -> { PrintResult.PasswordRequired -> {
ToastUtils.show(this,getString(R.string.pdf_cant_print_password_protected)) ToastUtils.show(
this,
getString(R.string.pdf_cant_print_password_protected)
)
} }
PrintResult.Success -> { PrintResult.Success -> {

View File

@ -544,14 +544,14 @@ class PdfResultActivity : BaseActivity() {
override fun shouldInterceptBackPress(): Boolean = isProcessing override fun shouldInterceptBackPress(): Boolean = isProcessing
override fun onInterceptBackPressed() { override fun onInterceptBackPressed() {
exitDialog = PromptDialogFragment( exitDialog = PromptDialogFragment.newInstance(
getString(R.string.tip), getString(R.string.tip),
getString(R.string.confirm_discard_changes), getString(R.string.confirm_discard_changes),
getString(R.string.discard), getString(R.string.discard))
onOkClick = { exitDialog?. onOkClick = {
backPressedCallback?.isEnabled = false backPressedCallback?.isEnabled = false
onBackPressedDispatcher.onBackPressed() onBackPressedDispatcher.onBackPressed()
}) }
exitDialog?.show(supportFragmentManager, getString(R.string.exit_split)) exitDialog?.show(supportFragmentManager, getString(R.string.exit_split))
} }

View File

@ -134,11 +134,15 @@ class PdfToImageActivity : BaseActivity() {
isPdfEncrypted(file) isPdfEncrypted(file)
} }
if (isEncrypted) { if (isEncrypted) {
PdfPasswordProtectionDialogFragment(file, onOkClick = { password -> val pdfPasswordProtectionDialogFragment =
PdfPasswordProtectionDialogFragment.newInstance(file.absolutePath)
pdfPasswordProtectionDialogFragment.onOkClick = { password ->
initSplitDataWithPassword(file, password) initSplitDataWithPassword(file, password)
}, onCancelClick = { }
pdfPasswordProtectionDialogFragment.onCancelClick = {
finish() finish()
}).show(supportFragmentManager, TAG) }
pdfPasswordProtectionDialogFragment.show(supportFragmentManager, TAG)
} else { } else {
initSplitDataWithPassword(file) initSplitDataWithPassword(file)
} }

View File

@ -11,18 +11,15 @@ import android.view.inputmethod.EditorInfo
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.all.pdfreader.pdf.reader.PRApp
import com.all.pdfreader.pdf.reader.R import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
import com.all.pdfreader.pdf.reader.ad.BannerManager import com.all.pdfreader.pdf.reader.ad.BannerManager
import com.all.pdfreader.pdf.reader.ad.ShowListener
import com.all.pdfreader.pdf.reader.databinding.ActivityPdfViewBinding import com.all.pdfreader.pdf.reader.databinding.ActivityPdfViewBinding
import com.all.pdfreader.pdf.reader.model.FileActionEvent import com.all.pdfreader.pdf.reader.model.FileActionEvent
import com.all.pdfreader.pdf.reader.room.entity.PdfDocumentEntity import com.all.pdfreader.pdf.reader.room.entity.PdfDocumentEntity
import com.all.pdfreader.pdf.reader.ui.dialog.BookmarksDialogFragment import com.all.pdfreader.pdf.reader.ui.dialog.BookmarksDialogFragment
import com.all.pdfreader.pdf.reader.ui.dialog.ListMoreDialogFragment import com.all.pdfreader.pdf.reader.ui.dialog.ListMoreDialogFragment
import com.all.pdfreader.pdf.reader.ui.dialog.PdfPasswordProtectionDialogFragment import com.all.pdfreader.pdf.reader.ui.dialog.PdfPasswordProtectionDialogFragment
import com.all.pdfreader.pdf.reader.ui.dialog.PermissionDialogFragment
import com.all.pdfreader.pdf.reader.ui.dialog.ViewModelDialogFragment import com.all.pdfreader.pdf.reader.ui.dialog.ViewModelDialogFragment
import com.all.pdfreader.pdf.reader.ui.view.CustomScrollHandle import com.all.pdfreader.pdf.reader.ui.view.CustomScrollHandle
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
@ -32,7 +29,6 @@ import com.all.pdfreader.pdf.reader.util.AppUtils.showKeyboard
import com.all.pdfreader.pdf.reader.util.FileUtils import com.all.pdfreader.pdf.reader.util.FileUtils
import com.all.pdfreader.pdf.reader.util.PDFHighlighter import com.all.pdfreader.pdf.reader.util.PDFHighlighter
import com.all.pdfreader.pdf.reader.util.PDFSearchManager import com.all.pdfreader.pdf.reader.util.PDFSearchManager
import com.all.pdfreader.pdf.reader.util.StoragePermissionHelper
import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel
import com.all.pdfreader.pdf.reader.viewmodel.observeEvent import com.all.pdfreader.pdf.reader.viewmodel.observeEvent
import com.github.barteksc.pdfviewer.listener.OnErrorListener import com.github.barteksc.pdfviewer.listener.OnErrorListener
@ -223,18 +219,21 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
ViewModelDialogFragment().show(supportFragmentManager, "ViewModelDialogFragment") ViewModelDialogFragment().show(supportFragmentManager, "ViewModelDialogFragment")
} }
binding.bookmarksBtn.setOnClickListener { binding.bookmarksBtn.setOnClickListener {
BookmarksDialogFragment(pdfDocument, onJumpPage = { val bookmarksDialogFragment = BookmarksDialogFragment.newInstance(pdfDocument)
bookmarksDialogFragment.onJumpPage = {
binding.pdfview.jumpTo(it) binding.pdfview.jumpTo(it)
binding.pdfview.postDelayed({ binding.pdfview.postDelayed({
binding.pdfview.resetZoomWithAnimation() binding.pdfview.resetZoomWithAnimation()
}, 200) }, 200)
}).show(supportFragmentManager, "BookmarksDialogFragment") }
bookmarksDialogFragment.show(supportFragmentManager, "BookmarksDialogFragment")
} }
binding.shareBtn.setOnClickListener { binding.shareBtn.setOnClickListener {
AppUtils.shareFile(this, File(pdfDocument.filePath)) AppUtils.shareFile(this, File(pdfDocument.filePath))
} }
binding.moreBtn.setOnClickListener { binding.moreBtn.setOnClickListener {
ListMoreDialogFragment(pdfDocument.filePath).show(supportFragmentManager, FRAG_TAG) ListMoreDialogFragment.newInstance(pdfDocument.filePath)
.show(supportFragmentManager, FRAG_TAG)
} }
binding.searchTextBtn.setOnClickListener { binding.searchTextBtn.setOnClickListener {
showSearchTextView = true showSearchTextView = true
@ -366,11 +365,15 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
} }
private fun showPasswordDialog(file: File) { private fun showPasswordDialog(file: File) {
PdfPasswordProtectionDialogFragment(file, onOkClick = { password -> val pdfPasswordProtectionDialogFragment =
PdfPasswordProtectionDialogFragment.newInstance(file.absolutePath)
pdfPasswordProtectionDialogFragment.onOkClick = { password ->
tryLoadPdfWithPassword(file, password) tryLoadPdfWithPassword(file, password)
}, onCancelClick = { }
pdfPasswordProtectionDialogFragment.onCancelClick = {
finish() finish()
}).show(supportFragmentManager, TAG) }
pdfPasswordProtectionDialogFragment.show(supportFragmentManager, TAG)
} }
private fun tryLoadPdfWithPassword(file: File, password: String) { private fun tryLoadPdfWithPassword(file: File, password: String) {
@ -582,7 +585,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
} }
override fun onDestroy() { override fun onDestroy() {
BannerManager.onDestroy(this,AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE) BannerManager.onDestroy(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
super.onDestroy() super.onDestroy()
if (::searchManager.isInitialized) { if (::searchManager.isInitialized) {
searchManager.closeCachedDocument() searchManager.closeCachedDocument()
@ -591,11 +594,11 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
BannerManager.onResume( this,AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE) BannerManager.onResume(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
} }
override fun onPause() { override fun onPause() {
BannerManager.onPause(this,AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE) BannerManager.onPause(this, AdsInsUtil.AdPlacement.BAN_AND_HOMEPAGE)
super.onPause() super.onPause()
} }
} }

View File

@ -134,15 +134,17 @@ class SearchActivity : BaseActivity() {
} }
binding.clearHistory.setOnClickListener { binding.clearHistory.setOnClickListener {
PromptDialogFragment( val promptDialogFragment = PromptDialogFragment.newInstance(
getString(R.string.tip), title = getString(R.string.tip),
getString(R.string.clear_history_desc), desc = getString(R.string.clear_history_desc),
getString(R.string.clear), okBtnText = getString(R.string.clear)
onOkClick = { )
searchHistory.clear() promptDialogFragment.onOkClick = {
saveHistoryList() // 保存空列表 searchHistory.clear()
showHistory() saveHistoryList() // 保存空列表
}).show(supportFragmentManager, "clearHistory") showHistory()
}
promptDialogFragment.show(supportFragmentManager, "clearHistory")
} }
} }
@ -173,25 +175,29 @@ class SearchActivity : BaseActivity() {
} }
PdfPickerSource.LOCK -> { PdfPickerSource.LOCK -> {
PdfSetPasswordDialog(onOkClick = { password -> val pdfSetPasswordDialog = PdfSetPasswordDialog.newInstance()
pdfSetPasswordDialog.onOkClick = { password ->
val intent = PdfResultActivity.createIntentLock( val intent = PdfResultActivity.createIntentLock(
this, pdf.filePath, password, PdfPickerSource.LOCK this, pdf.filePath, password, PdfPickerSource.LOCK
) )
startActivity(intent) startActivity(intent)
setResult(RESULT_OK)//通知选择界面关闭 setResult(RESULT_OK)//通知选择界面关闭
finish() finish()
}).show(supportFragmentManager, "PdfSetPasswordDialog") }
pdfSetPasswordDialog.show(supportFragmentManager, "PdfSetPasswordDialog")
} }
PdfPickerSource.UNLOCK -> { PdfPickerSource.UNLOCK -> {
PdfRemovePasswordDialog(pdf.filePath, onOkClick = { password -> val pdfRemovePasswordDialog = PdfRemovePasswordDialog.newInstance(pdf.filePath)
pdfRemovePasswordDialog.onOkClick = { password ->
val intent = PdfResultActivity.createIntentLock( val intent = PdfResultActivity.createIntentLock(
this, pdf.filePath, password, PdfPickerSource.UNLOCK this, pdf.filePath, password, PdfPickerSource.UNLOCK
) )
startActivity(intent) startActivity(intent)
setResult(RESULT_OK) setResult(RESULT_OK)
finish() finish()
}).show(supportFragmentManager, "PdfRemovePasswordDialog") }
pdfRemovePasswordDialog.show(supportFragmentManager, "PdfRemovePasswordDialog")
} }
PdfPickerSource.IMAGES_TO_PDF -> {} PdfPickerSource.IMAGES_TO_PDF -> {}
@ -233,7 +239,7 @@ class SearchActivity : BaseActivity() {
} }
} }
}, onMoreClick = { pdf -> }, onMoreClick = { pdf ->
ListMoreDialogFragment(pdf.filePath).show(supportFragmentManager, FRAG_TAG) ListMoreDialogFragment.newInstance(pdf.filePath).show(supportFragmentManager, FRAG_TAG)
}) })
binding.recyclerView.layoutManager = LinearLayoutManager(this) binding.recyclerView.layoutManager = LinearLayoutManager(this)

View File

@ -4,7 +4,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.activity.OnBackPressedCallback
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -26,7 +25,6 @@ import com.all.pdfreader.pdf.reader.util.FileUtils.isPdfEncrypted
import com.all.pdfreader.pdf.reader.util.FileUtils.toUnderscoreDateTime import com.all.pdfreader.pdf.reader.util.FileUtils.toUnderscoreDateTime
import com.all.pdfreader.pdf.reader.util.PdfUtils import com.all.pdfreader.pdf.reader.util.PdfUtils
import com.all.pdfreader.pdf.reader.util.ToastUtils import com.all.pdfreader.pdf.reader.util.ToastUtils
import com.gyf.immersionbar.ImmersionBar
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@ -104,11 +102,16 @@ class SplitPdfActivity : BaseActivity() {
binding.splitRv.adapter = adapter binding.splitRv.adapter = adapter
selectedPdfAdapter = SplitSelectedPdfAdapter(selectedList, onEditClick = { item, pos -> selectedPdfAdapter = SplitSelectedPdfAdapter(selectedList, onEditClick = { item, pos ->
RenameDialogFragment( val renameDialogFragment = RenameDialogFragment.newInstance(
RenameType.NAME, null, item.fileName, onOkClickString = { string -> type = RenameType.NAME,
selectedList[pos].fileName = string bookmark = null,
selectedPdfAdapter.updateItem(pos) name = item.fileName
}).show(supportFragmentManager, "SplitPdfActivity") )
renameDialogFragment.onOkClickString = { string ->
selectedList[pos].fileName = string
selectedPdfAdapter.updateItem(pos)
}
renameDialogFragment.show(supportFragmentManager, "SplitPdfActivity")
}, onDeleteClick = { item, pos -> }, onDeleteClick = { item, pos ->
selectedList.remove(item) selectedList.remove(item)
selectedPdfAdapter.removeItem(pos) selectedPdfAdapter.removeItem(pos)
@ -166,11 +169,15 @@ class SplitPdfActivity : BaseActivity() {
isPdfEncrypted(file) isPdfEncrypted(file)
} }
if (isEncrypted) { if (isEncrypted) {
PdfPasswordProtectionDialogFragment(file, onOkClick = { password -> val pdfPasswordProtectionDialogFragment =
PdfPasswordProtectionDialogFragment.newInstance(file.absolutePath)
pdfPasswordProtectionDialogFragment.onOkClick = { password ->
initSplitDataWithPassword(file, password) initSplitDataWithPassword(file, password)
}, onCancelClick = { }
pdfPasswordProtectionDialogFragment.onCancelClick = {
finish() finish()
}).show(supportFragmentManager, TAG) }
pdfPasswordProtectionDialogFragment.show(supportFragmentManager, TAG)
} else { } else {
initSplitDataWithPassword(file) initSplitDataWithPassword(file)
} }
@ -299,16 +306,18 @@ class SplitPdfActivity : BaseActivity() {
when (currentViewState) { when (currentViewState) {
ViewState.SPLIT_SELECTED -> { ViewState.SPLIT_SELECTED -> {
// 已选页面列表,提示是否退出 // 已选页面列表,提示是否退出
PromptDialogFragment( val promptDialogFragment = PromptDialogFragment.newInstance(
getString(R.string.exit_split), title = getString(R.string.exit_split),
getString(R.string.confirm_discard_changes), desc = getString(R.string.confirm_discard_changes),
getString(R.string.discard), okBtnText = getString(R.string.discard)
onOkClick = { )
backPressedCallback?.isEnabled = false promptDialogFragment.onOkClick = {
onBackPressedDispatcher.onBackPressed() backPressedCallback?.isEnabled = false
onBackPressedDispatcher.onBackPressed()
AnalyticsUtils.logEvent(AnalyticsUtils.Event.SPLIT_LEAVE_CONFIRM) AnalyticsUtils.logEvent(AnalyticsUtils.Event.SPLIT_LEAVE_CONFIRM)
}).show(supportFragmentManager, getString(R.string.exit_split)) }
promptDialogFragment.show(supportFragmentManager, getString(R.string.exit_split))
} }
ViewState.SPLIT_LIST -> { ViewState.SPLIT_LIST -> {

View File

@ -4,6 +4,7 @@ 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 androidx.fragment.app.FragmentManager
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.all.pdfreader.pdf.reader.R import com.all.pdfreader.pdf.reader.R
@ -17,9 +18,29 @@ import com.all.pdfreader.pdf.reader.util.ToastUtils
import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class BookmarksDialogFragment( class BookmarksDialogFragment() : BottomSheetDialogFragment() {
private val pdfDocument: PdfDocumentEntity, private val onJumpPage: (Int) -> Unit
) : BottomSheetDialogFragment() { companion object {
private const val ARG_FILE_PATH = "arg_file_path"
private const val ARG_LAST_READ_PAGE = "arg_last_read_page"
fun newInstance(pdfDocument: PdfDocumentEntity): BookmarksDialogFragment {
val fragment = BookmarksDialogFragment()
val args = Bundle()
args.putString(ARG_FILE_PATH, pdfDocument.filePath)
args.putInt(ARG_LAST_READ_PAGE, pdfDocument.lastReadPage)
fragment.arguments = args
return fragment
}
}
private val filePath: String
get() = arguments?.getString(ARG_FILE_PATH) ?: ""
private val lastReadPage: Int
get() = arguments?.getInt(ARG_LAST_READ_PAGE) ?: 0
var onJumpPage: ((Int) -> Unit)? = null
private lateinit var binding: DialogBookmarksBinding private lateinit var binding: DialogBookmarksBinding
private val viewModel: PdfViewModel by activityViewModels()//为PdfViewActivity的PdfViewModel private val viewModel: PdfViewModel by activityViewModels()//为PdfViewActivity的PdfViewModel
@ -28,7 +49,10 @@ class BookmarksDialogFragment(
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
dismissAllowingStateLoss()
return
}
/** /**
* BottomSheetDialogFragment 覆盖底部导航栏 * BottomSheetDialogFragment 覆盖底部导航栏
* 原理 * 原理
@ -41,10 +65,17 @@ class BookmarksDialogFragment(
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View? {
if (savedInstanceState != null) return null
binding = DialogBookmarksBinding.inflate(layoutInflater) binding = DialogBookmarksBinding.inflate(layoutInflater)
return binding.root return binding.root
} }
override fun show(manager: FragmentManager, tag: String?) {
if (!manager.isStateSaved) {
super.show(manager, tag)
}
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) dialog?.window?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
@ -54,7 +85,7 @@ class BookmarksDialogFragment(
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
AnalyticsUtils.logEvent(AnalyticsUtils.Event.BOOKMARK_TK_SHOW) AnalyticsUtils.logEvent(AnalyticsUtils.Event.BOOKMARK_TK_SHOW)
if (pdfDocument.filePath.isEmpty()) { if (filePath.isEmpty()) {
showToast(getString(R.string.file_not)) showToast(getString(R.string.file_not))
dismiss() dismiss()
} }
@ -70,15 +101,19 @@ class BookmarksDialogFragment(
private fun initView() { private fun initView() {
adapter = BookmarkAdapter(list = mutableListOf(), onItemClick = { bookmark -> adapter = BookmarkAdapter(list = mutableListOf(), onItemClick = { bookmark ->
onJumpPage(bookmark.pageNumber) onJumpPage?.invoke(bookmark.pageNumber)
dismiss() dismiss()
}, onEditClick = { bookmark, position -> }, onEditClick = { bookmark, position ->
RenameDialogFragment(RenameType.BOOKMARK, bookmark, onOkClick = { updatedBookmark -> val renameDialogFragment = RenameDialogFragment.newInstance(
RenameType.BOOKMARK, bookmark
)
renameDialogFragment.onOkClick = { updatedBookmark ->
bookmarks = bookmarks.map {//更新外部数据 bookmarks = bookmarks.map {//更新外部数据
if (it.id == updatedBookmark.id) updatedBookmark else it if (it.id == updatedBookmark.id) updatedBookmark else it
} }
adapter.updateItemChanged(updatedBookmark)//更新adapter数据 adapter.updateItemChanged(updatedBookmark)//更新adapter数据
}).show( }
renameDialogFragment.show(
parentFragmentManager, "BookmarksDialogFragment" parentFragmentManager, "BookmarksDialogFragment"
) )
}, onDeleteClick = { bookmark, position -> }, onDeleteClick = { bookmark, position ->
@ -92,7 +127,7 @@ class BookmarksDialogFragment(
updateAdapter() updateAdapter()
} }
private fun updateUi(){ private fun updateUi() {
if (bookmarks.isEmpty()) { if (bookmarks.isEmpty()) {
binding.noBookmarksPageLayout.visibility = View.VISIBLE//显示没有书签的提示布局 binding.noBookmarksPageLayout.visibility = View.VISIBLE//显示没有书签的提示布局
binding.bookmarksDisplayLayout.visibility = View.GONE//隐藏显示内容的布局 binding.bookmarksDisplayLayout.visibility = View.GONE//隐藏显示内容的布局
@ -102,7 +137,7 @@ class BookmarksDialogFragment(
binding.bookmarksDisplayLayout.visibility = View.VISIBLE binding.bookmarksDisplayLayout.visibility = View.VISIBLE
binding.addBtn.visibility = View.VISIBLE binding.addBtn.visibility = View.VISIBLE
// 检查当前页是否已存在书签 // 检查当前页是否已存在书签
val alreadyBookmarked = bookmarks.any { it.pageNumber == pdfDocument.lastReadPage } val alreadyBookmarked = bookmarks.any { it.pageNumber == lastReadPage }
binding.addBtn.isEnabled = !alreadyBookmarked binding.addBtn.isEnabled = !alreadyBookmarked
if (alreadyBookmarked) { if (alreadyBookmarked) {
binding.addTv.text = getString(R.string.added) binding.addTv.text = getString(R.string.added)
@ -126,23 +161,25 @@ class BookmarksDialogFragment(
dialogAddBookMarks() dialogAddBookMarks()
} }
binding.deleteALLPageBtn.setOnClickListener { binding.deleteALLPageBtn.setOnClickListener {
PromptDialogFragment( val promptDialogFragment = PromptDialogFragment.newInstance(
getString(R.string.delete_bookmarks_title), title = getString(R.string.delete_bookmarks_title),
getString(R.string.delete_bookmarks_desc), desc = getString(R.string.delete_bookmarks_desc)
onOkClick = { )
viewModel.deleteAllBookmark(pdfDocument.filePath) promptDialogFragment.onOkClick = {
adapter.removeAllItems() viewModel.deleteAllBookmark(filePath)
bookmarks = emptyList() adapter.removeAllItems()
updateUi() bookmarks = emptyList()
}).show(parentFragmentManager, "deleteAllBookmark") updateUi()
}
promptDialogFragment.show(parentFragmentManager, "deleteAllBookmark")
} }
} }
private fun dialogAddBookMarks() { private fun dialogAddBookMarks() {
val bookmark = BookmarkEntity( val bookmark = BookmarkEntity(
filePath = pdfDocument.filePath, filePath = filePath,
pageNumber = pdfDocument.lastReadPage, pageNumber = lastReadPage,
label = getString(R.string.page) + " ${pdfDocument.lastReadPage + 1}" label = getString(R.string.page) + " ${lastReadPage + 1}"
) )
viewModel.addBookMark(bookmark) viewModel.addBookMark(bookmark)
dismiss() dismiss()

View File

@ -5,6 +5,7 @@ import android.util.Log
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 androidx.fragment.app.FragmentManager
import com.all.pdfreader.pdf.reader.R import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.ad.AdsInsUtil import com.all.pdfreader.pdf.reader.ad.AdsInsUtil
import com.all.pdfreader.pdf.reader.ad.NativeAdCache import com.all.pdfreader.pdf.reader.ad.NativeAdCache
@ -13,23 +14,33 @@ import com.all.pdfreader.pdf.reader.databinding.DialogExitBinding
import com.google.android.gms.ads.nativead.NativeAd import com.google.android.gms.ads.nativead.NativeAd
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class ExitDialogFragment( class ExitDialogFragment() : BottomSheetDialogFragment() {
private val onExitClick: () -> Unit, var onExitClick: (() -> Unit)? = null
) : BottomSheetDialogFragment() {
private lateinit var binding: DialogExitBinding private lateinit var binding: DialogExitBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
dismissAllowingStateLoss()
return
}
setStyle(STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme) setStyle(STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme)
} }
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View { ): View? {
if (savedInstanceState != null) return null
binding = DialogExitBinding.inflate(layoutInflater) binding = DialogExitBinding.inflate(layoutInflater)
return binding.root return binding.root
} }
override fun show(manager: FragmentManager, tag: String?) {
if (!manager.isStateSaved) {
super.show(manager, tag)
}
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) dialog?.window?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
@ -51,7 +62,7 @@ class ExitDialogFragment(
private fun setupOnClick() { private fun setupOnClick() {
binding.exitBtn.setOnClickListener { binding.exitBtn.setOnClickListener {
onExitClick() onExitClick?.invoke()
dismiss() dismiss()
} }
} }

View File

@ -23,9 +23,7 @@ import com.all.pdfreader.pdf.reader.util.ToastUtils
import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel
import java.io.File import java.io.File
class GotoPageDialogFragment( class GotoPageDialogFragment() : DialogFragment() {
private val onOkClick: () -> Unit = {},
) : DialogFragment() {
private lateinit var binding: DialogGotoPageBinding private lateinit var binding: DialogGotoPageBinding
private val viewModel: PdfViewModel by activityViewModels() private val viewModel: PdfViewModel by activityViewModels()

View File

@ -5,7 +5,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.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.all.pdfreader.pdf.reader.R import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.databinding.DialogListMoreBinding import com.all.pdfreader.pdf.reader.databinding.DialogListMoreBinding
@ -36,7 +35,20 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import java.io.File import java.io.File
class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment() { class ListMoreDialogFragment() : BottomSheetDialogFragment() {
companion object {
private const val ARG_FILE_PATH = "arg_file_path"
fun newInstance(filePath: String): ListMoreDialogFragment {
val fragment = ListMoreDialogFragment()
val args = Bundle()
args.putString(ARG_FILE_PATH, filePath)
fragment.arguments = args
return fragment
}
}
private val filePath: String
get() = arguments?.getString(ARG_FILE_PATH) ?: ""
private lateinit var binding: DialogListMoreBinding private lateinit var binding: DialogListMoreBinding
private val viewModel: PdfViewModel by activityViewModels() private val viewModel: PdfViewModel by activityViewModels()
@ -140,18 +152,21 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
dismiss() dismiss()
} }
binding.renameFileBtn.setOnClickListener { binding.renameFileBtn.setOnClickListener {
RenameDialogFragment(RenameType.FILE).show( val renameDialogFragment = RenameDialogFragment.newInstance(RenameType.FILE)
renameDialogFragment.show(
parentFragmentManager, "ListMoreDialogFragment" parentFragmentManager, "ListMoreDialogFragment"
) )
dismiss() dismiss()
} }
binding.deleteFileBtn.setOnClickListener { binding.deleteFileBtn.setOnClickListener {
PromptDialogFragment( val promptDialogFragment = PromptDialogFragment.newInstance(
getString(R.string.delete_file_title), title = getString(R.string.delete_file_title),
getString(R.string.delete_file_desc), desc = getString(R.string.delete_file_desc)
onOkClick = { )
viewModel.deleteFile(pdfDocument.filePath) promptDialogFragment.onOkClick = {
}).show(parentFragmentManager, "deleteFile") viewModel.deleteFile(pdfDocument.filePath)
}
promptDialogFragment.show(parentFragmentManager, "deleteFile")
dismiss() dismiss()
} }
binding.detailsBtn.setOnClickListener { binding.detailsBtn.setOnClickListener {
@ -194,26 +209,33 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
} }
binding.setPasswordBtn.setOnClickListener { binding.setPasswordBtn.setOnClickListener {
if (pdfDocument.isPassword) { if (pdfDocument.isPassword) {
PdfRemovePasswordDialog(pdfDocument.filePath, onOkClick = { password -> val pdfRemovePasswordDialog = PdfRemovePasswordDialog.newInstance(pdfDocument.filePath)
pdfRemovePasswordDialog.onOkClick = { password ->
viewModel.removePassword(pdfDocument.filePath, password) viewModel.removePassword(pdfDocument.filePath, password)
}).show(parentFragmentManager, "PdfRemovePasswordDialog") }
pdfRemovePasswordDialog.show(parentFragmentManager, "PdfRemovePasswordDialog")
} else { } else {
PdfSetPasswordDialog(onOkClick = { password -> val pdfSetPasswordDialog = PdfSetPasswordDialog.newInstance()
pdfSetPasswordDialog.onOkClick = { password ->
viewModel.setPassword(pdfDocument.filePath, password) viewModel.setPassword(pdfDocument.filePath, password)
}).show(parentFragmentManager, "PdfSetPasswordDialog") }
pdfSetPasswordDialog.show(parentFragmentManager, "PdfSetPasswordDialog")
} }
dismiss() dismiss()
} }
binding.removeRecentBtn.setOnClickListener { binding.removeRecentBtn.setOnClickListener {
AnalyticsUtils.logEvent(AnalyticsUtils.Event.REMOVE_CK) AnalyticsUtils.logEvent(AnalyticsUtils.Event.REMOVE_CK)
PromptDialogFragment(
getString(R.string.remove_dialog_title), val promptDialogFragment = PromptDialogFragment.newInstance(
getString(R.string.remove_dialog_desc), title = getString(R.string.remove_dialog_title),
getString(R.string.remove), desc = getString(R.string.remove_dialog_desc),
onOkClick = { okBtnText = getString(R.string.remove)
viewModel.removeRecent(pdfDocument.filePath) )
AnalyticsUtils.logEvent(AnalyticsUtils.Event.REMOVE_SUCCESS) promptDialogFragment.onOkClick = {
}).show(parentFragmentManager, "removeRecent") viewModel.removeRecent(pdfDocument.filePath)
AnalyticsUtils.logEvent(AnalyticsUtils.Event.REMOVE_SUCCESS)
}
promptDialogFragment.show(parentFragmentManager, "removeRecent")
dismiss() dismiss()
} }
binding.splitBtn.setOnClickListener { binding.splitBtn.setOnClickListener {

View File

@ -21,15 +21,39 @@ import com.all.pdfreader.pdf.reader.util.AppUtils.showKeyboard
import com.all.pdfreader.pdf.reader.util.FileUtils.isPdfPasswordCorrect import com.all.pdfreader.pdf.reader.util.FileUtils.isPdfPasswordCorrect
import java.io.File import java.io.File
class PdfPasswordProtectionDialogFragment( class PdfPasswordProtectionDialogFragment() : DialogFragment() {
private val file: File,
private val onOkClick: (String) -> Unit, companion object {
private val onCancelClick: () -> Unit, private const val ARG_FILE_PATH = "arg_file_path"
private val isPrompt: Boolean = false private const val ARG_IS_PROMPT = "arg_is_prompt"
) : DialogFragment() {
fun newInstance(filePath: String, isPrompt: Boolean = false): PdfPasswordProtectionDialogFragment {
val fragment = PdfPasswordProtectionDialogFragment()
val args = Bundle()
args.putString(ARG_FILE_PATH, filePath)
args.putBoolean(ARG_IS_PROMPT, isPrompt)
fragment.arguments = args
return fragment
}
}
// 外部设置回调
var onOkClick: ((String) -> Unit)? = null
var onCancelClick: (() -> Unit)? = null
private val file: File
get() = File(arguments?.getString(ARG_FILE_PATH) ?: "")
private val isPrompt: Boolean
get() = arguments?.getBoolean(ARG_IS_PROMPT) ?: false
private lateinit var binding: DialogPdfPasswordProtectionBinding private lateinit var binding: DialogPdfPasswordProtectionBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View? {
@ -69,7 +93,7 @@ class PdfPasswordProtectionDialogFragment(
} }
binding.cancelBtn.setOnClickListener { binding.cancelBtn.setOnClickListener {
onCancelClick() onCancelClick?.invoke()
dismiss() dismiss()
} }
binding.okBtn.setOnClickListener { binding.okBtn.setOnClickListener {
@ -79,7 +103,7 @@ class PdfPasswordProtectionDialogFragment(
return@setOnClickListener return@setOnClickListener
} }
if (isPdfPasswordCorrect(requireActivity(), file, password)) { if (isPdfPasswordCorrect(requireActivity(), file, password)) {
onOkClick(password) onOkClick?.invoke(password)
dismiss() dismiss()
} else { } else {
binding.tilPassword.error = getString(R.string.incorrect_password) binding.tilPassword.error = getString(R.string.incorrect_password)

View File

@ -15,17 +15,41 @@ import com.all.pdfreader.pdf.reader.util.FileUtils.isPdfPasswordCorrect
import com.all.pdfreader.pdf.reader.util.ToastUtils import com.all.pdfreader.pdf.reader.util.ToastUtils
import java.io.File import java.io.File
class PdfRemovePasswordDialog( class PdfRemovePasswordDialog() : DialogFragment() {
val filePath: String,
val onOkClick: (password: String) -> Unit = {} companion object {
) : private const val ARG_FILE_PATH = "arg_file_path"
DialogFragment() {
fun newInstance(filePath: String): PdfRemovePasswordDialog {
val fragment = PdfRemovePasswordDialog()
val args = Bundle()
args.putString(ARG_FILE_PATH, filePath)
fragment.arguments = args
return fragment
}
}
var onOkClick: ((password: String) -> Unit)? = null
private lateinit var binding: DialogPdfRemovePasswordBinding private lateinit var binding: DialogPdfRemovePasswordBinding
private val filePath: String
get() = arguments?.getString(ARG_FILE_PATH) ?: ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 系统恢复时直接关闭,防止 crash
if (savedInstanceState != null) {
dismissAllowingStateLoss()
return
}
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View? {
binding = DialogPdfRemovePasswordBinding.inflate(layoutInflater) if (savedInstanceState != null) return null
binding = DialogPdfRemovePasswordBinding.inflate(inflater, container, false)
return binding.root return binding.root
} }
@ -33,10 +57,8 @@ class PdfRemovePasswordDialog(
super.onStart() super.onStart()
isCancelable = false isCancelable = false
dialog?.window?.apply { dialog?.window?.apply {
// 去掉系统默认的背景 padding
setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// 设置宽度为全屏减去 16dp val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin)
val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin) // 16dp
val width = resources.displayMetrics.widthPixels - margin * 2 val width = resources.displayMetrics.widthPixels - margin * 2
setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT) setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT)
} }
@ -56,16 +78,13 @@ class PdfRemovePasswordDialog(
binding.okBtn.setOnClickListener { binding.okBtn.setOnClickListener {
val password = binding.etPassword.text.toString() val password = binding.etPassword.text.toString()
if (isPdfPasswordCorrect(requireActivity(), File(filePath), password)) { val file = File(filePath)
onOkClick(password) if (isPdfPasswordCorrect(requireActivity(), file, password)) {
onOkClick?.invoke(password)
dismiss() dismiss()
} else { } else {
binding.tilPassword.error = getString(R.string.incorrect_password) binding.tilPassword.error = getString(R.string.incorrect_password)
} }
} }
} }
}
private fun showToast(message: String) {
ToastUtils.show(requireActivity(), message)
}
}

View File

@ -15,15 +15,32 @@ import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.all.pdfreader.pdf.reader.util.AppUtils.showKeyboard import com.all.pdfreader.pdf.reader.util.AppUtils.showKeyboard
import com.all.pdfreader.pdf.reader.util.ToastUtils import com.all.pdfreader.pdf.reader.util.ToastUtils
class PdfSetPasswordDialog( class PdfSetPasswordDialog() : DialogFragment() {
private val onOkClick: (password: String) -> Unit = {}
) : DialogFragment() { companion object {
fun newInstance(): PdfSetPasswordDialog {
return PdfSetPasswordDialog()
}
}
var onOkClick: ((password: String) -> Unit)? = null
private lateinit var binding: DialogPdfSetPasswordBinding private lateinit var binding: DialogPdfSetPasswordBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 系统恢复时直接 dismiss 避免 crash
if (savedInstanceState != null) {
dismissAllowingStateLoss()
return
}
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View? {
binding = DialogPdfSetPasswordBinding.inflate(layoutInflater) if (savedInstanceState != null) return null
binding = DialogPdfSetPasswordBinding.inflate(inflater, container, false)
return binding.root return binding.root
} }
@ -31,10 +48,8 @@ class PdfSetPasswordDialog(
super.onStart() super.onStart()
isCancelable = false isCancelable = false
dialog?.window?.apply { dialog?.window?.apply {
// 去掉系统默认的背景 padding
setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// 设置宽度为全屏减去 16dp val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin)
val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin) // 16dp
val width = resources.displayMetrics.widthPixels - margin * 2 val width = resources.displayMetrics.widthPixels - margin * 2
setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT) setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT)
} }
@ -57,7 +72,7 @@ class PdfSetPasswordDialog(
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)) {
onOkClick(password) onOkClick?.invoke(password)
dismiss() dismiss()
} }
} }
@ -97,19 +112,16 @@ class PdfSetPasswordDialog(
binding.tilPassword.error = null binding.tilPassword.error = null
binding.tilConfirmPassword.error = null binding.tilConfirmPassword.error = null
// 不允许空密码
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 false return false
} }
// 密码长度验证
if (password.length < 4) { if (password.length < 4) {
binding.tilPassword.error = getString(R.string.password_too_short) binding.tilPassword.error = getString(R.string.password_too_short)
return false return false
} }
// 密码匹配验证
if (password != confirmPassword) { if (password != confirmPassword) {
binding.tilConfirmPassword.error = getString(R.string.password_not_match) binding.tilConfirmPassword.error = getString(R.string.password_not_match)
return false return false
@ -117,8 +129,4 @@ class PdfSetPasswordDialog(
return true return true
} }
}
private fun showToast(message: String) {
ToastUtils.show(requireActivity(), message)
}
}

View File

@ -12,55 +12,82 @@ import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.databinding.DialogDeleteBinding import com.all.pdfreader.pdf.reader.databinding.DialogDeleteBinding
import com.all.pdfreader.pdf.reader.util.ToastUtils import com.all.pdfreader.pdf.reader.util.ToastUtils
class PromptDialogFragment( class PromptDialogFragment() : DialogFragment() {
private val title: String,
private val desc: String, companion object {
private val okBtnText: String? = null, private const val ARG_TITLE = "arg_title"
private val onOkClick: () -> Unit, private const val ARG_DESC = "arg_desc"
private val onCancelClick: () -> Unit = {} private const val ARG_OK_TEXT = "arg_ok_text"
) : DialogFragment() {
fun newInstance(
title: String,
desc: String,
okBtnText: String? = null
): PromptDialogFragment {
val fragment = PromptDialogFragment()
val args = Bundle()
args.putString(ARG_TITLE, title)
args.putString(ARG_DESC, desc)
args.putString(ARG_OK_TEXT, okBtnText)
fragment.arguments = args
return fragment
}
}
var onOkClick: (() -> Unit)? = null
var onCancelClick: (() -> Unit)? = null
private val title: String
get() = arguments?.getString(ARG_TITLE) ?: ""
private val desc: String
get() = arguments?.getString(ARG_DESC) ?: ""
private val okBtnText: String?
get() = arguments?.getString(ARG_OK_TEXT)
private lateinit var binding: DialogDeleteBinding private lateinit var binding: DialogDeleteBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 系统恢复时直接 dismiss 避免 crash
if (savedInstanceState != null) {
dismissAllowingStateLoss()
return
}
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View? {
binding = DialogDeleteBinding.inflate(layoutInflater) if (savedInstanceState != null) return null
binding = DialogDeleteBinding.inflate(inflater, container, false)
return binding.root return binding.root
} }
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.apply { dialog?.window?.apply {
// 去掉系统默认的背景 padding
setBackgroundDrawable(Color.TRANSPARENT.toDrawable()) setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
// 设置宽度为全屏减去 16dp val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin)
val margin = resources.getDimensionPixelSize(R.dimen.dialog_margin) // 16dp
val width = resources.displayMetrics.widthPixels - margin * 2 val width = resources.displayMetrics.widthPixels - margin * 2
setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT) 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)
if (okBtnText.isNullOrEmpty()) {
binding.okBtnTv.text = getString(R.string.delete)
} else {
binding.okBtnTv.text = okBtnText
}
binding.deleteTitleTv.text = title binding.deleteTitleTv.text = title
binding.deleteDescTv.text = desc binding.deleteDescTv.text = desc
binding.okBtnTv.text = okBtnText ?: getString(R.string.delete)
setupOnClick() setupOnClick()
} }
private fun setupOnClick() { private fun setupOnClick() {
binding.okBtn.setOnClickListener { binding.okBtn.setOnClickListener {
onOkClick() onOkClick?.invoke()
dismiss() dismiss()
} }
binding.cancelBtn.setOnClickListener { binding.cancelBtn.setOnClickListener {
onCancelClick() onCancelClick?.invoke()
dismiss() dismiss()
} }
} }
@ -68,4 +95,4 @@ class PromptDialogFragment(
private fun showToast(message: String) { private fun showToast(message: String) {
ToastUtils.show(requireActivity(), message) ToastUtils.show(requireActivity(), message)
} }
} }

View File

@ -22,17 +22,42 @@ import com.all.pdfreader.pdf.reader.util.ToastUtils
import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel import com.all.pdfreader.pdf.reader.viewmodel.PdfViewModel
import java.io.File import java.io.File
class RenameDialogFragment( class RenameDialogFragment() : DialogFragment() {
private val type: RenameType, companion object {
private val bookmark: BookmarkEntity? = null, private const val ARG_TYPE = "arg_type"
private val name: String? = null, private const val ARG_BOOKMARK = "arg_bookmark"
private val onOkClick: (BookmarkEntity) -> Unit = {}, private const val ARG_NAME = "arg_name"
private val onOkClickString: (String) -> Unit = {}
) : DialogFragment() { fun newInstance(
type: RenameType,
bookmark: BookmarkEntity? = null,
name: String? = null
): RenameDialogFragment {
val fragment = RenameDialogFragment()
val args = Bundle()
args.putString(ARG_TYPE, type.name)
if (bookmark != null) args.putParcelable(ARG_BOOKMARK, bookmark)
if (name != null) args.putString(ARG_NAME, name)
fragment.arguments = args
return fragment
}
}
private lateinit var binding: DialogRenameFileBinding private lateinit var binding: DialogRenameFileBinding
private val viewModel: PdfViewModel by activityViewModels() private val viewModel: PdfViewModel by activityViewModels()
private val type: RenameType
get() = RenameType.valueOf(arguments?.getString(ARG_TYPE) ?: RenameType.FILE.name)
private val bookmark: BookmarkEntity?
get() = arguments?.getParcelable(ARG_BOOKMARK)
private val name: String?
get() = arguments?.getString(ARG_NAME)
var onOkClick: ((BookmarkEntity) -> Unit)? = null
var onOkClickString: ((String) -> Unit)? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View? {
@ -114,7 +139,7 @@ class RenameDialogFragment(
if (validateEnter(text, oldName, filePath)) { if (validateEnter(text, oldName, filePath)) {
val new = bookmark?.copy(label = text)!! val new = bookmark?.copy(label = text)!!
viewModel.updateBookmark(new) viewModel.updateBookmark(new)
onOkClick(new) onOkClick?.invoke(new)
dismiss() dismiss()
} }
} }
@ -122,7 +147,7 @@ class RenameDialogFragment(
RenameType.NAME -> { RenameType.NAME -> {
val text = binding.etName.text.toString() val text = binding.etName.text.toString()
if (validateEnter(text, oldName, filePath)) { if (validateEnter(text, oldName, filePath)) {
onOkClickString(text) onOkClickString?.invoke(text)
dismiss() dismiss()
} }
} }

View File

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import com.all.pdfreader.pdf.reader.R import com.all.pdfreader.pdf.reader.R
import com.all.pdfreader.pdf.reader.databinding.DialogSortBinding import com.all.pdfreader.pdf.reader.databinding.DialogSortBinding
import com.all.pdfreader.pdf.reader.model.SortConfig import com.all.pdfreader.pdf.reader.model.SortConfig
@ -16,10 +17,26 @@ import com.all.pdfreader.pdf.reader.ui.fragment.HomeFrag
import com.all.pdfreader.pdf.reader.util.AnalyticsUtils import com.all.pdfreader.pdf.reader.util.AnalyticsUtils
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class SortDialogFragment( class SortDialogFragment() : BottomSheetDialogFragment() {
private val fragment: Fragment,
private val onOkClick: (String) -> Unit
) : BottomSheetDialogFragment() { companion object {
private const val ARG_FRAGMENT_TAG = "arg_fragment_tag"
fun newInstance(fragmentTag: String): SortDialogFragment {
val frag = SortDialogFragment()
val args = Bundle()
args.putString(ARG_FRAGMENT_TAG, fragmentTag)
frag.arguments = args
return frag
}
}
private val fragmentTag: String
get() = arguments?.getString(ARG_FRAGMENT_TAG) ?: ""
var onOkClick: ((String) -> Unit)? = null // 可选回调,正常显示时使用
private lateinit var binding: DialogSortBinding private lateinit var binding: DialogSortBinding
private lateinit var sortConfig: SortConfig private lateinit var sortConfig: SortConfig
@ -28,16 +45,31 @@ class SortDialogFragment(
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
// 极端情况下这种类型的dialogFragment在恢复的时候会报错临时的dialog就不进行恢复处理防止崩溃
// 如果系统正在恢复这个 DialogFragment 直接 dismiss 避免 crash
if (savedInstanceState != null) {
dismissAllowingStateLoss()
return
}
setStyle(STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme) setStyle(STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme)
} }
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? { ): View? {
// 如果是恢复状态,不创建 view
if (savedInstanceState != null) return null
binding = DialogSortBinding.inflate(layoutInflater) binding = DialogSortBinding.inflate(layoutInflater)
return binding.root return binding.root
} }
override fun show(manager: FragmentManager, tag: String?) {
if (!manager.isStateSaved) {
super.show(manager, tag)
}
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) dialog?.window?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
@ -49,13 +81,10 @@ class SortDialogFragment(
AnalyticsUtils.logEvent(AnalyticsUtils.Event.SORT_SHOW) AnalyticsUtils.logEvent(AnalyticsUtils.Event.SORT_SHOW)
val appStore = AppStore(requireActivity()) val appStore = AppStore(requireActivity())
isCancelable = false isCancelable = false
when(fragment){ sortConfig = when(fragmentTag) {
is HomeFrag->{ HomeFrag::class.java.simpleName -> SortConfig.fromPreferenceString(appStore.documentSortType)
sortConfig = SortConfig.fromPreferenceString(appStore.documentSortType) FavoriteFrag::class.java.simpleName -> SortConfig.fromPreferenceString(appStore.favoriteSortType)
} else -> SortConfig.fromPreferenceString(appStore.documentSortType)
is FavoriteFrag->{
sortConfig = SortConfig.fromPreferenceString(appStore.favoriteSortType)
}
} }
updateUi(sortConfig) updateUi(sortConfig)
selectedField = sortConfig.field selectedField = sortConfig.field
@ -90,10 +119,8 @@ class SortDialogFragment(
dismiss() dismiss()
} }
binding.okBtn.setOnClickListener { binding.okBtn.setOnClickListener {
val newConfig = SortConfig( val newConfig = SortConfig(field = selectedField, direction = selectedDirection)
field = selectedField, direction = selectedDirection onOkClick?.invoke(newConfig.toPreferenceString())
)
onOkClick(newConfig.toPreferenceString())
dismiss() dismiss()
} }
} }

View File

@ -24,7 +24,7 @@ import com.all.pdfreader.pdf.reader.ui.dialog.SortDialogFragment
import com.all.pdfreader.pdf.reader.util.AppUtils.setOnSingleClickListener import com.all.pdfreader.pdf.reader.util.AppUtils.setOnSingleClickListener
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class FavoriteFrag : BaseFrag(){ class FavoriteFrag : BaseFrag() {
override val TAG: String = "FavoriteFrag" override val TAG: String = "FavoriteFrag"
companion object { companion object {
@ -66,7 +66,7 @@ class FavoriteFrag : BaseFrag(){
val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath) val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath)
startActivity(intent) startActivity(intent)
}, onMoreClick = { pdf -> }, onMoreClick = { pdf ->
ListMoreDialogFragment(pdf.filePath).show(parentFragmentManager, FRAG_TAG) ListMoreDialogFragment.newInstance(pdf.filePath).show(parentFragmentManager, FRAG_TAG)
}, onLongClick = { pdf -> }, onLongClick = { pdf ->
setupMultiSelect() setupMultiSelect()
}, onSelectModelItemClick = { number -> }, onSelectModelItemClick = { number ->
@ -84,10 +84,12 @@ class FavoriteFrag : BaseFrag(){
} }
binding.sortingBtn.setOnSingleClickListener { binding.sortingBtn.setOnSingleClickListener {
SortDialogFragment(FavoriteFrag(), onOkClick = { it -> val dialog = SortDialogFragment.newInstance(FavoriteFrag::class.java.simpleName)
updateSortUi(it) dialog.onOkClick = { result ->
onSortFavoriteTypeChanged(it) updateSortUi(result)
}).show(parentFragmentManager, TAG) onSortFavoriteTypeChanged(result)
}
dialog.show(parentFragmentManager, TAG)
} }
} }

View File

@ -64,7 +64,7 @@ class HomeFrag : BaseFrag(){
val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath) val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath)
startActivity(intent) startActivity(intent)
}, onMoreClick = { pdf -> }, onMoreClick = { pdf ->
ListMoreDialogFragment(pdf.filePath).show(parentFragmentManager, FRAG_TAG) ListMoreDialogFragment.newInstance(pdf.filePath).show(parentFragmentManager, FRAG_TAG)
}, onLongClick = { pdf -> }, onLongClick = { pdf ->
setupMultiSelect() setupMultiSelect()
}, onSelectModelItemClick = { number -> }, onSelectModelItemClick = { number ->
@ -85,10 +85,12 @@ class HomeFrag : BaseFrag(){
} }
binding.sortingBtn.setOnSingleClickListener { binding.sortingBtn.setOnSingleClickListener {
SortDialogFragment(HomeFrag(), onOkClick = { it -> val dialog = SortDialogFragment.newInstance(HomeFrag::class.java.simpleName)
updateSortUi(it) dialog.onOkClick = { result ->
onSortTypeChanged(it) updateSortUi(result)
}).show(parentFragmentManager, TAG) onSortTypeChanged(result)
}
dialog.show(parentFragmentManager, TAG)
} }
} }

View File

@ -59,7 +59,7 @@ class RecentlyFrag : BaseFrag() {
val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath) val intent = PdfViewActivity.createIntent(requireContext(), pdf.filePath)
startActivity(intent) startActivity(intent)
}, onMoreClick = { pdf -> }, onMoreClick = { pdf ->
ListMoreDialogFragment(pdf.filePath).show(parentFragmentManager, FRAG_TAG) ListMoreDialogFragment.newInstance(pdf.filePath).show(parentFragmentManager, FRAG_TAG)
}, onLongClick = { pdf -> }, onLongClick = { pdf ->
setupMultiSelect() setupMultiSelect()
}, onSelectModelItemClick = { number -> }, onSelectModelItemClick = { number ->