diff --git a/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt b/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt index e84d8de..bb7f878 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/model/FileActionEvent.kt @@ -22,6 +22,7 @@ sealed class FileActionEvent { object NoticeReload : FileActionEvent() data class AddBookmark(val success: Boolean) : FileActionEvent() + data class UpdateBookmark(val success: Boolean) : FileActionEvent() data class DeleteBookmark(val success: Boolean) : FileActionEvent() data class DeleteAllBookmark(val success: Boolean) : FileActionEvent() } \ No newline at end of file diff --git a/app/src/main/java/com/all/pdfreader/pro/app/model/RenameConfig.kt b/app/src/main/java/com/all/pdfreader/pro/app/model/RenameConfig.kt new file mode 100644 index 0000000..6643aaa --- /dev/null +++ b/app/src/main/java/com/all/pdfreader/pro/app/model/RenameConfig.kt @@ -0,0 +1,6 @@ +package com.all.pdfreader.pro.app.model + +enum class RenameType { + FILE, // 修改文件名 + BOOKMARK // 修改书签名 +} 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 a7e12dd..b916a26 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 @@ -3,10 +3,8 @@ package com.all.pdfreader.pro.app.ui.act import android.content.Context import android.content.Intent import android.os.Bundle -import android.util.Log import android.view.MotionEvent import android.view.View -import androidx.core.os.HandlerCompat.postDelayed import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.lifecycleScope import com.all.pdfreader.pro.app.R diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/BookmarkAdapter.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/BookmarkAdapter.kt index 53357cf..1282b55 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/BookmarkAdapter.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/adapter/BookmarkAdapter.kt @@ -10,7 +10,7 @@ import com.all.pdfreader.pro.app.room.entity.BookmarkEntity class BookmarkAdapter( private var list: MutableList, private val onItemClick: (BookmarkEntity) -> Unit, - private val onEditClick: (BookmarkEntity) -> Unit, + private val onEditClick: (BookmarkEntity, Int) -> Unit, private val onDeleteClick: (BookmarkEntity, Int) -> Unit, ) : RecyclerView.Adapter() { @@ -35,7 +35,7 @@ class BookmarkAdapter( onItemClick(item) } holder.binding.editBtn.setOnClickListener { - onEditClick(item) + onEditClick(item, position) } holder.binding.deleteBtn.setOnClickListener { onDeleteClick(item, position) @@ -51,6 +51,16 @@ class BookmarkAdapter( notifyDataSetChanged() } + fun updateItemChanged(updatedBookmark: BookmarkEntity) { + val index = list.indexOfFirst { it.id == updatedBookmark.id } + if (index != -1) { + list = list.toMutableList().apply { + this[index] = updatedBookmark + } + notifyItemChanged(index) + } + } + fun removeItem(position: Int) { list.removeAt(position) notifyItemRemoved(position) diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/BookmarksDialogFragment.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/BookmarksDialogFragment.kt index 834a640..e388d94 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/BookmarksDialogFragment.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/BookmarksDialogFragment.kt @@ -10,6 +10,7 @@ import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.LinearLayoutManager import com.all.pdfreader.pro.app.R import com.all.pdfreader.pro.app.databinding.DialogBookmarksBinding +import com.all.pdfreader.pro.app.model.RenameType import com.all.pdfreader.pro.app.room.entity.BookmarkEntity import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity import com.all.pdfreader.pro.app.ui.adapter.BookmarkAdapter @@ -17,10 +18,8 @@ import com.all.pdfreader.pro.app.viewmodel.PdfViewModel import com.google.android.material.bottomsheet.BottomSheetDialogFragment class BookmarksDialogFragment( - private val pdfDocument: PdfDocumentEntity, - private val onJumpPage: (Int) -> Unit -) : - BottomSheetDialogFragment() { + private val pdfDocument: PdfDocumentEntity, private val onJumpPage: (Int) -> Unit +) : BottomSheetDialogFragment() { private lateinit var binding: DialogBookmarksBinding private val viewModel: PdfViewModel by activityViewModels()//为PdfViewActivity的PdfViewModel @@ -58,24 +57,29 @@ class BookmarksDialogFragment( showToast(getString(R.string.file_not)) dismiss() } - //观察书签数据 - viewModel.pdfBookmark.observe(this) { list -> - Log.d("ocean","BookmarksDialogFragment observe") - list?.let { - bookmarks = it - initView() - setupOnClick() - } + viewModel.pdfBookmark.value?.let { + bookmarks = it + initView() + setupOnClick() + } ?: run { + showToast(getString(R.string.bookmark_loading)) + dismiss() } - viewModel.getBookmarks(pdfDocument.filePath) } private fun initView() { adapter = BookmarkAdapter(list = mutableListOf(), onItemClick = { bookmark -> onJumpPage(bookmark.pageNumber) dismiss() - }, onEditClick = { bookmark -> - + }, onEditClick = { bookmark, position -> + RenameDialogFragment(RenameType.BOOKMARK, bookmark, onOkClick = { updatedBookmark -> + bookmarks = bookmarks.map {//更新外部数据 + if (it.id == updatedBookmark.id) updatedBookmark else it + } + adapter.updateItemChanged(updatedBookmark)//更新adapter数据 + }).show( + parentFragmentManager, "BookmarksDialogFragment" + ) }, onDeleteClick = { bookmark, position -> adapter.removeItem(position) bookmarks = bookmarks.filter { it.id != bookmark.id } @@ -83,7 +87,11 @@ class BookmarksDialogFragment( }) binding.bookmarksPageRv.layoutManager = LinearLayoutManager(requireContext()) binding.bookmarksPageRv.adapter = adapter + updateUi() + updateAdapter() + } + private fun updateUi(){ if (bookmarks.isEmpty()) { binding.noBookmarksPageLayout.visibility = View.VISIBLE//显示没有书签的提示布局 binding.bookmarksDisplayLayout.visibility = View.GONE//隐藏显示内容的布局 @@ -106,8 +114,6 @@ class BookmarksDialogFragment( binding.addBtn.setBackgroundResource(R.drawable.dr_click_btn_red_bg) binding.addIv.setImageResource(R.drawable.add_icon_white) } - - updateAdapter() } } @@ -126,6 +132,7 @@ class BookmarksDialogFragment( viewModel.deleteAllBookmark(pdfDocument.filePath) adapter.removeAllItems() bookmarks = emptyList() + updateUi() }).show(parentFragmentManager, "DeleteDialogFragment") } } @@ -134,7 +141,7 @@ class BookmarksDialogFragment( val bookmark = BookmarkEntity( filePath = pdfDocument.filePath, pageNumber = pdfDocument.lastReadPage, - label = getString(R.string.page) + "${pdfDocument.lastReadPage + 1}" + label = getString(R.string.page) + " ${pdfDocument.lastReadPage + 1}" ) viewModel.addBookMark(bookmark) dismiss() diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt index 2eb59b8..60f7581 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/ListMoreDialogFragment.kt @@ -10,6 +10,7 @@ import androidx.fragment.app.activityViewModels import com.all.pdfreader.pro.app.R import com.all.pdfreader.pro.app.databinding.DialogListMoreBinding import com.all.pdfreader.pro.app.model.PrintResult +import com.all.pdfreader.pro.app.model.RenameType import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity import com.all.pdfreader.pro.app.util.AppUtils.dpToPx import com.all.pdfreader.pro.app.util.AppUtils.printPdfFile @@ -95,7 +96,10 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment() dismiss() } binding.renameFileBtn.setOnClickListener { - RenameDialogFragment().show(parentFragmentManager, "ListMoreDialogFragment") + RenameDialogFragment(RenameType.FILE).show( + parentFragmentManager, + "ListMoreDialogFragment" + ) dismiss() } binding.deleteFileBtn.setOnClickListener { diff --git a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/RenameDialogFragment.kt b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/RenameDialogFragment.kt index 28be373..a5be105 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/RenameDialogFragment.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/ui/dialog/RenameDialogFragment.kt @@ -13,17 +13,21 @@ import androidx.fragment.app.DialogFragment import androidx.fragment.app.activityViewModels import com.all.pdfreader.pro.app.R import com.all.pdfreader.pro.app.databinding.DialogRenameFileBinding -import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity +import com.all.pdfreader.pro.app.model.RenameType +import com.all.pdfreader.pro.app.room.entity.BookmarkEntity import com.all.pdfreader.pro.app.util.AppUtils.showKeyboard import com.all.pdfreader.pro.app.util.FileUtils import com.all.pdfreader.pro.app.viewmodel.PdfViewModel import java.io.File -class RenameDialogFragment() : DialogFragment() { +class RenameDialogFragment( + private val type: RenameType, + private val bookmark: BookmarkEntity? = null, + private val onOkClick: (BookmarkEntity) -> Unit= {} +) : DialogFragment() { private lateinit var binding: DialogRenameFileBinding private val viewModel: PdfViewModel by activityViewModels() - private lateinit var pdfDocument: PdfDocumentEntity override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -47,34 +51,61 @@ class RenameDialogFragment() : DialogFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - viewModel.pdfDocument.value?.let { - pdfDocument = it - initView() - setupOnClick() - } ?: run { - showToast(getString(R.string.file_not)) - dismiss() + when (type) { + RenameType.FILE -> { + viewModel.pdfDocument.value?.let { + initView(it.fileName) + setupOnClick(it.fileName, it.filePath, null) + } ?: run { + showToast(getString(R.string.file_not)) + dismiss() + } + } + + RenameType.BOOKMARK -> { + bookmark?.let { + initView(it.label) + setupOnClick(it.label, it.filePath, it) + } ?: run { + showToast(getString(R.string.file_not)) + dismiss() + } + } } } - private fun initView() { + private fun initView(name: String) { binding.etName.showKeyboard() - binding.etName.setText(FileUtils.removeFileExtension(pdfDocument.fileName)) + binding.etName.setText(FileUtils.removeFileExtension(name)) // 保持光标在末尾 binding.etName.setSelection(binding.etName.text?.length ?: 0) - } - private fun setupOnClick() { + private fun setupOnClick(oldName: String, filePath: String, bookmark: BookmarkEntity?) { binding.tvCancel.setOnClickListener { dismiss() } binding.tvConfirm.setOnClickListener { - val text = binding.etName.text.toString() - if (validateEnter(text)) { - viewModel.renamePdf(pdfDocument.filePath, text) - dismiss() + when (type) { + RenameType.FILE -> { + val text = binding.etName.text.toString() + if (validateEnter(text, oldName, filePath)) { + viewModel.renamePdf(filePath, text) + dismiss() + } + } + + RenameType.BOOKMARK -> { + val text = binding.etName.text.toString() + if (validateEnter(text, oldName, filePath)) { + val new = bookmark?.copy(label = text)!! + viewModel.updateBookmark(new) + onOkClick(new) + dismiss() + } + } } + } binding.etName.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} @@ -86,19 +117,13 @@ class RenameDialogFragment() : DialogFragment() { }) } - private fun validateEnter(name: String): Boolean { + private fun validateEnter(name: String, oldName: String, filePath: String): Boolean { // 不允许为空 if (name.isBlank()) { binding.tilName.error = getString(R.string.name_not_empty) return false } - // 名字未做修改(因展示的时候去掉了扩展名,则判断的时候也去掉) - if (name == FileUtils.removeFileExtension(pdfDocument.fileName)) { - binding.tilName.error = getString(R.string.name_not_changed) - return false - } - // 含有非法字符 val invalidChars = "[/\\\\:*?\"<>|.]".toRegex() if (invalidChars.containsMatchIn(name)) { @@ -106,17 +131,36 @@ class RenameDialogFragment() : DialogFragment() { return false } - // 长度过长 - if (name.length > 255) { - binding.tilName.error = getString(R.string.name_too_long) - return false - } + when (type) { + //只有修改文件名称时,才进行以下判断 + RenameType.FILE -> { + if (name.length > 255) { + binding.tilName.error = getString(R.string.name_too_long) + return false + } + // 名字未做修改(因展示的时候去掉了扩展名,则判断的时候也去掉) + if (name == FileUtils.removeFileExtension(oldName)) { + binding.tilName.error = getString(R.string.name_not_changed) + return false + } + // 与现有文件重名 + val parentDir = File(filePath).parentFile + if (parentDir != null && File(parentDir, name).exists()) { + binding.tilName.error = getString(R.string.name_already_exists) + return false + } + } - // 与现有文件重名 - val parentDir = File(pdfDocument.filePath).parentFile - if (parentDir != null && File(parentDir, name).exists()) { - binding.tilName.error = getString(R.string.name_already_exists) - return false + RenameType.BOOKMARK -> { + if (name.length > 50) { + binding.tilName.error = getString(R.string.name_too_long) + return false + } + if (name == oldName) { + binding.tilName.error = getString(R.string.name_not_changed) + return false + } + } } // 禁止开头/结尾空格 diff --git a/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt b/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt index 1575bd1..a1c5642 100644 --- a/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt +++ b/app/src/main/java/com/all/pdfreader/pro/app/viewmodel/PdfViewModel.kt @@ -18,6 +18,7 @@ import com.all.pdfreader.pro.app.util.FileUtils.isPdfEncrypted import com.all.pdfreader.pro.app.util.PdfMetadataExtractor import com.all.pdfreader.pro.app.util.PdfSecurityUtils import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File @@ -202,7 +203,7 @@ class PdfViewModel : ViewModel() { fun getBookmarks(filePath: String) { viewModelScope.launch { Log.d("ocean", "getBookmarks->filePath: $filePath") - pdfRepository.getBookmarksByPdf(filePath).collect { bookmarks -> + pdfRepository.getBookmarksByPdf(filePath).distinctUntilChanged().collect { bookmarks -> _pdfBookmark.value = bookmarks } } @@ -217,10 +218,20 @@ class PdfViewModel : ViewModel() { } } + fun updateBookmark(bookmark: BookmarkEntity){ + viewModelScope.launch { + val int = pdfRepository.updateBookmark(bookmark) + val success = int > 0 + Log.d("ocean", "updateBookmark->success: $success") + _fileActionEvent.postValue(FileActionEvent.UpdateBookmark(success)) + } + } + fun deleteBookMark(bookmark: BookmarkEntity) { viewModelScope.launch { val int = pdfRepository.deleteBookmark(bookmark) val success = int > 0//受影响行数大于0 + Log.d("ocean", "deleteBookmark->success: $success") _fileActionEvent.postValue(FileActionEvent.DeleteBookmark(success)) } } @@ -229,6 +240,7 @@ class PdfViewModel : ViewModel() { viewModelScope.launch { val int = pdfRepository.deleteAllBookmark(filePath) val success = int > 0 + Log.d("ocean", "deleteAllBookmark->success: $success") _fileActionEvent.postValue(FileActionEvent.DeleteAllBookmark(success)) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3f5dd6d..1c51d9e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -113,4 +113,5 @@ Bookmark remove Delete Bookmarks Are you sure you want to delete all Bookmarks? + Loading bookmarks, please try again later \ No newline at end of file