添加pdf拆分二级功能界面。
This commit is contained in:
parent
06a2720547
commit
df84891d91
@ -1,10 +1,14 @@
|
||||
package com.all.pdfreader.pro.app.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* 拆分pdf,展示用的每页信息
|
||||
*/
|
||||
@Parcelize
|
||||
data class PdfPageItem(
|
||||
val pageIndex: Int,
|
||||
var previewFilePath: String?, // 缓存文件路径
|
||||
var isSelected: Boolean
|
||||
)
|
||||
) : Parcelable
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.all.pdfreader.pro.app.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* 拆分pdf,被选中使用的结构
|
||||
*/
|
||||
@Parcelize
|
||||
data class PdfSelectedPagesItem(
|
||||
val filePath: String,
|
||||
var fileName: String, // 文件名
|
||||
val pages: List<PdfPageItem> // 所有页的数据
|
||||
): Parcelable {
|
||||
/**
|
||||
* 获取已选中的页面列表
|
||||
*/
|
||||
fun selectedPages(): List<PdfPageItem> =
|
||||
pages.filter { it.isSelected }.sortedBy { it.pageIndex }
|
||||
|
||||
/**
|
||||
* 获取已选中的页码字符串,例如 "1,2,3,4,6"
|
||||
*/
|
||||
fun selectedPageNumbersString(): String =
|
||||
selectedPages().joinToString(",") { (it.pageIndex + 1).toString() }
|
||||
|
||||
/**
|
||||
* 获取第一个图片,没有返回空字符串
|
||||
*/
|
||||
fun getFirstThumbPath(): String = pages.first().previewFilePath ?: ""
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.all.pdfreader.pro.app.model
|
||||
|
||||
data class PdfSplitResultItem(
|
||||
val filePath: String,
|
||||
val thumbnailPath: String? = null,
|
||||
var isSelected: Boolean
|
||||
)
|
||||
@ -2,5 +2,6 @@ package com.all.pdfreader.pro.app.model
|
||||
|
||||
enum class RenameType {
|
||||
FILE, // 修改文件名
|
||||
BOOKMARK // 修改书签名
|
||||
BOOKMARK, // 修改书签名
|
||||
NAME // 修改集合的item名称
|
||||
}
|
||||
|
||||
@ -4,14 +4,22 @@ import android.content.Context
|
||||
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
|
||||
import com.all.pdfreader.pro.app.databinding.ActivityPdfSplitBinding
|
||||
import com.all.pdfreader.pro.app.model.PdfPageItem
|
||||
import com.all.pdfreader.pro.app.model.PdfSelectedPagesItem
|
||||
import com.all.pdfreader.pro.app.model.RenameType
|
||||
import com.all.pdfreader.pro.app.ui.adapter.SplitPdfAdapter
|
||||
import com.all.pdfreader.pro.app.ui.adapter.SplitSelectedPdfAdapter
|
||||
import com.all.pdfreader.pro.app.ui.dialog.PromptDialogFragment
|
||||
import com.all.pdfreader.pro.app.ui.dialog.RenameDialogFragment
|
||||
import com.all.pdfreader.pro.app.util.FileUtils.toUnderscoreDateTime
|
||||
import com.all.pdfreader.pro.app.util.PdfUtils
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import kotlinx.coroutines.launch
|
||||
@ -33,14 +41,19 @@ class SplitPdfActivity : BaseActivity() {
|
||||
private lateinit var binding: ActivityPdfSplitBinding
|
||||
private lateinit var adapter: SplitPdfAdapter
|
||||
private var splitList: MutableList<PdfPageItem> = mutableListOf()
|
||||
private var selectedList: MutableList<PdfSelectedPagesItem> = mutableListOf()
|
||||
private lateinit var selectedPdfAdapter: SplitSelectedPdfAdapter
|
||||
private var isSelectedViewShow = false//用于返回的时候是否提示(点击了继续按钮就会产生提示)
|
||||
private lateinit var filePath: String
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityPdfSplitBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
setupBackPressedCallback()
|
||||
ImmersionBar.with(this).statusBarView(binding.view).statusBarDarkFont(true)
|
||||
.navigationBarColor(R.color.white).init()
|
||||
val filePath = intent.getStringExtra(EXTRA_PDF_PATH)
|
||||
.navigationBarColor(R.color.bg_color).init()
|
||||
filePath = intent.getStringExtra(EXTRA_PDF_PATH)
|
||||
?: throw IllegalArgumentException("PDF file hash is required")
|
||||
if (filePath.isEmpty()) {
|
||||
showToast(getString(R.string.file_not))
|
||||
@ -52,40 +65,77 @@ class SplitPdfActivity : BaseActivity() {
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
binding.continueNowBtn.isEnabled = false
|
||||
binding.title.text = getString(R.string.selected_page, 0)
|
||||
binding.selectAllBtn.visibility = View.GONE
|
||||
binding.loadingRoot.root.visibility = View.VISIBLE
|
||||
binding.selectAllBtn.visibility = View.GONE//初始隐藏全选按钮
|
||||
binding.addBtn.visibility = View.GONE//初始隐藏add按钮
|
||||
binding.loadingRoot.root.visibility = View.VISIBLE//初始显示loading
|
||||
binding.splitRv.layoutManager = GridLayoutManager(this, 2)
|
||||
adapter = SplitPdfAdapter(splitList) { item, pos ->
|
||||
item.isSelected = !item.isSelected
|
||||
adapter.setItemSelected(pos, item.isSelected)
|
||||
binding.title.text = getString(R.string.selected_page, adapter.getSelPages())
|
||||
|
||||
// 只有存在选中的item则为true
|
||||
val anySelected = splitList.any { it.isSelected }
|
||||
binding.continueNowBtn.isEnabled = anySelected
|
||||
updateContinueNowBtnState(anySelected)
|
||||
}
|
||||
binding.splitRv.adapter = adapter
|
||||
|
||||
selectedPdfAdapter = SplitSelectedPdfAdapter(selectedList, onEditClick = { item, pos ->
|
||||
RenameDialogFragment(
|
||||
RenameType.NAME, null, item.fileName, onOkClickString = { string ->
|
||||
selectedList[pos].fileName = string
|
||||
selectedPdfAdapter.updateItem(pos)
|
||||
}).show(supportFragmentManager, "BookmarksDialogFragment")
|
||||
}, onDeleteClick = { item, pos ->
|
||||
selectedList.remove(item)
|
||||
selectedPdfAdapter.removeItem(pos)
|
||||
updateSplitBtnState(selectedList.isNotEmpty())
|
||||
})
|
||||
binding.splitSelectRv.layoutManager = LinearLayoutManager(this)
|
||||
binding.splitSelectRv.adapter = selectedPdfAdapter
|
||||
}
|
||||
|
||||
private fun setupClick() {
|
||||
binding.backBtn.setOnClickListener { finish() }
|
||||
binding.backBtn.setOnClickListener { onBackPressedDispatcher.onBackPressed() }
|
||||
binding.selectAllBtn.setOnClickListener {
|
||||
val selectAll = splitList.any { !it.isSelected }
|
||||
val selectAll = splitList.any { !it.isSelected }//如果列表里有一页没选中 → 返回 true
|
||||
adapter.setAllSelected(selectAll)
|
||||
binding.title.text = getString(R.string.selected_page, adapter.getSelPages())
|
||||
|
||||
if (selectAll) {
|
||||
binding.selectAll.setBackgroundResource(R.drawable.dr_circular_sel_on_bg)
|
||||
} else {
|
||||
binding.selectAll.setBackgroundResource(R.drawable.dr_circular_sel_off_bg)
|
||||
binding.continueNowBtn.isEnabled = selectAll
|
||||
updateSelectAllState(selectAll)
|
||||
updateContinueNowBtnState(selectAll)
|
||||
}
|
||||
binding.continueNowBtn.setOnClickListener {
|
||||
val selectedPages = splitList.filter { it.isSelected }.map { it.copy() }
|
||||
val name =
|
||||
getString(R.string.split) + "_" + System.currentTimeMillis().toUnderscoreDateTime()
|
||||
val item = PdfSelectedPagesItem(filePath, name, selectedPages)
|
||||
selectedList.add(item)
|
||||
selectedPdfAdapter.updateAdapter()
|
||||
isSelectedViewShow = true
|
||||
updateViewState(true)
|
||||
}
|
||||
binding.addBtn.setOnClickListener {
|
||||
//点击重新添加后,选中状态全部置为false,全选按钮置为false
|
||||
adapter.setAllSelected(false)
|
||||
updateSelectAllState(false)
|
||||
updateViewState(false)
|
||||
}
|
||||
binding.splitBtn.setOnClickListener {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun initSplitData(file: File) {
|
||||
lifecycleScope.launch {
|
||||
splitList.clear()
|
||||
PdfUtils.clearPdfThumbsCache(this@SplitPdfActivity) // 先清理旧缓存
|
||||
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
var firstPageLoaded = false
|
||||
PdfUtils.splitPdfToPageItemsFlow(this@SplitPdfActivity, file).collect { pageItem ->
|
||||
logDebug("pageItem flow ->$pageItem")
|
||||
if (splitList.size <= pageItem.pageIndex) {
|
||||
splitList.add(pageItem)
|
||||
adapter.notifyItemInserted(splitList.size - 1)
|
||||
@ -93,20 +143,106 @@ class SplitPdfActivity : BaseActivity() {
|
||||
splitList[pageItem.pageIndex] = pageItem
|
||||
adapter.updateItem(pageItem.pageIndex)
|
||||
}
|
||||
if (!firstPageLoaded) {
|
||||
if (!firstPageLoaded) {//有数据回来则隐藏loading,显示全选按钮
|
||||
binding.loadingRoot.root.visibility = View.GONE
|
||||
binding.selectAllBtn.visibility = View.VISIBLE
|
||||
firstPageLoaded = true
|
||||
}
|
||||
}
|
||||
binding.loadingRoot.root.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSelectAllState(b: Boolean) {
|
||||
binding.selectAll.setBackgroundResource(
|
||||
if (b) R.drawable.dr_circular_sel_on_bg
|
||||
else R.drawable.dr_circular_sel_off_bg
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateContinueNowBtnState(b: Boolean) {
|
||||
binding.continueNowBtn.setBackgroundResource(
|
||||
if (b) R.drawable.dr_click_btn_bg
|
||||
else R.drawable.dr_btn_not_clickable_bg
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateSplitBtnState(b: Boolean) {
|
||||
binding.splitBtn.setBackgroundResource(
|
||||
if (b) R.drawable.dr_click_btn_bg
|
||||
else R.drawable.dr_btn_not_clickable_bg
|
||||
)
|
||||
}
|
||||
|
||||
private fun updateViewState(b: Boolean) {
|
||||
if (b) {
|
||||
binding.selectAllBtn.visibility = View.GONE//隐藏全选按钮
|
||||
binding.addBtn.visibility = View.VISIBLE//显示add按钮
|
||||
binding.title.text = getString(R.string.split_pdf)//设置标题
|
||||
} else {
|
||||
binding.selectAllBtn.visibility = View.VISIBLE
|
||||
binding.addBtn.visibility = View.GONE
|
||||
binding.title.text =
|
||||
getString(R.string.selected_page, adapter.getSelPages())//重新设置标题为选中了多少个
|
||||
}
|
||||
updateViewStateWithAnimation(b)
|
||||
|
||||
updateSplitBtnState(selectedList.isNotEmpty())
|
||||
}
|
||||
|
||||
private fun updateViewStateWithAnimation(showSelectedView: Boolean) {
|
||||
if (showSelectedView) {
|
||||
// 切换到已选页面列表
|
||||
binding.splitListLayout.animate().translationY(-50f).alpha(0f).setDuration(200)
|
||||
.withEndAction {
|
||||
binding.splitListLayout.visibility = View.GONE
|
||||
binding.splitListLayout.translationY = 0f
|
||||
}.start()
|
||||
|
||||
binding.splitSelectLayout.alpha = 0f
|
||||
binding.splitSelectLayout.translationY = 50f
|
||||
binding.splitSelectLayout.visibility = View.VISIBLE
|
||||
binding.splitSelectLayout.animate().translationY(0f).alpha(1f).setDuration(200).start()
|
||||
} else {
|
||||
// 切回拆分页列表
|
||||
binding.splitSelectLayout.animate().translationY(50f).alpha(0f).setDuration(200)
|
||||
.withEndAction {
|
||||
binding.splitSelectLayout.visibility = View.GONE
|
||||
binding.splitSelectLayout.translationY = 0f
|
||||
}.start()
|
||||
|
||||
binding.splitListLayout.alpha = 0f
|
||||
binding.splitListLayout.translationY = -50f
|
||||
binding.splitListLayout.visibility = View.VISIBLE
|
||||
binding.splitListLayout.animate().translationY(0f).alpha(1f).setDuration(200).start()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
splitList.clear()
|
||||
PdfUtils.clearPdfThumbsCache(this)
|
||||
}
|
||||
|
||||
private fun setupBackPressedCallback() {
|
||||
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
if (isSelectedViewShow) {
|
||||
//使用提示对话框
|
||||
PromptDialogFragment(
|
||||
getString(R.string.exit_split),
|
||||
getString(R.string.confirm_discard_changes),
|
||||
getString(R.string.discard),
|
||||
onOkClick = {
|
||||
isEnabled = false
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}).show(supportFragmentManager, getString(R.string.exit_split))
|
||||
} else {
|
||||
isEnabled = false
|
||||
onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package com.all.pdfreader.pro.app.ui.act
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import com.all.pdfreader.pro.app.databinding.ActivityPdfSplitResultBinding
|
||||
import com.all.pdfreader.pro.app.model.PdfPageItem
|
||||
import com.all.pdfreader.pro.app.model.PdfSelectedPagesItem
|
||||
import com.all.pdfreader.pro.app.model.PdfSplitResultItem
|
||||
import com.all.pdfreader.pro.app.ui.act.SplitPdfActivity
|
||||
import com.all.pdfreader.pro.app.ui.adapter.SplitPdfResultAdapter
|
||||
import com.all.pdfreader.pro.app.util.PdfUtils
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
|
||||
class SplitPdfResultActivity : BaseActivity() {
|
||||
override val TAG: String = "SplitPdfResultActivity"
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_SELECTED_LIST = "extra_selected_list"
|
||||
|
||||
fun createIntent(
|
||||
context: Context,
|
||||
selectedPageIndices: List<Int>
|
||||
): Intent {
|
||||
return Intent(context, SplitPdfResultActivity::class.java).apply {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var binding: ActivityPdfSplitResultBinding
|
||||
private lateinit var adapter: SplitPdfResultAdapter
|
||||
private var splitResultList: MutableList<PdfSplitResultItem> = mutableListOf()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityPdfSplitResultBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ImmersionBar.with(this).statusBarView(binding.view).statusBarDarkFont(true)
|
||||
.navigationBarColor(R.color.bg_color).init()
|
||||
initView()
|
||||
setupClick()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
adapter = SplitPdfResultAdapter(splitResultList)
|
||||
binding.recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
}
|
||||
|
||||
private fun startSplittingPDF(
|
||||
inputFile: File, selectedPages: List<PdfPageItem>, outputDir: File, outputFileName: String
|
||||
) {
|
||||
lifecycleScope.launch {
|
||||
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
val resultFile = PdfUtils.exportSelectedPages(
|
||||
inputFile = inputFile,
|
||||
selectedPages = selectedPages,
|
||||
outputDir = outputDir,
|
||||
outputFileName = outputFileName,
|
||||
onProgress = { current, total ->
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupClick() {
|
||||
binding.backBtn.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
}
|
||||
@ -51,10 +51,12 @@ class SplitPdfAdapter(
|
||||
holder.binding.apply {
|
||||
//更新文字图片与选中状态
|
||||
pageNumberTv.text = "${item.pageIndex + 1}"
|
||||
if (item.previewFilePath != null) {
|
||||
Glide.with(holder.binding.root)
|
||||
.load(File(item.previewFilePath ?: ""))
|
||||
.transform(CenterCrop(), RoundedCorners(8.dpToPx(holder.binding.root.context)))
|
||||
.into(image)
|
||||
}
|
||||
bindSelection(item, holder)
|
||||
}
|
||||
holder.binding.root.setOnClickListener {
|
||||
@ -74,7 +76,7 @@ class SplitPdfAdapter(
|
||||
private fun bindSelection(item: PdfPageItem, holder: PdfViewHolder) {
|
||||
val b = holder.binding
|
||||
val selRes =
|
||||
if (item.isSelected) R.drawable.dr_circular_sel_on_bg else R.drawable.dr_circular_sel_off_bg
|
||||
if (item.isSelected) R.drawable.dr_item_page_img_sel_on_bg else R.drawable.dr_item_page_img_sel_off_bg
|
||||
b.selIv.setBackgroundResource(selRes)
|
||||
|
||||
val bgRes = if (item.isSelected) R.drawable.dr_sel_on_frame else R.drawable.dr_sel_off_frame
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
package com.all.pdfreader.pro.app.ui.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
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.model.PdfSplitResultItem
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.dpToPx
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import java.io.File
|
||||
|
||||
class SplitPdfResultAdapter(
|
||||
private val list: MutableList<PdfSplitResultItem>
|
||||
) : RecyclerView.Adapter<SplitPdfResultAdapter.PdfViewHolder>() {
|
||||
|
||||
inner class PdfViewHolder(val binding: AdapterSplitSelectedResultItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = PdfViewHolder(
|
||||
AdapterSplitSelectedResultItemBinding.inflate(
|
||||
LayoutInflater.from(parent.context), parent, false
|
||||
)
|
||||
)
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: PdfViewHolder, position: Int) {
|
||||
val item = list[position]
|
||||
if (item.thumbnailPath != null) {
|
||||
Glide.with(holder.binding.root).load(File(item.thumbnailPath))
|
||||
.transform(CenterCrop(), RoundedCorners(8.dpToPx(holder.binding.root.context)))
|
||||
.into(holder.binding.image)
|
||||
}
|
||||
holder.binding.nameTv.text = File(item.filePath).name
|
||||
holder.binding.pathTv.text =
|
||||
holder.binding.root.context.getString(R.string.path_details, item.filePath)
|
||||
if (item.isSelected) {
|
||||
holder.binding.selectIv.visibility = View.VISIBLE
|
||||
} else {
|
||||
holder.binding.selectIv.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = list.size
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateAdapter() {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun updateItem(position: Int) = notifyItemChanged(position)
|
||||
|
||||
fun removeItem(position: Int) = notifyItemRemoved(position)
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.all.pdfreader.pro.app.ui.adapter
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.all.pdfreader.pro.app.databinding.AdapterSplitSelectedPageItemBinding
|
||||
import com.all.pdfreader.pro.app.model.PdfSelectedPagesItem
|
||||
import com.all.pdfreader.pro.app.util.AppUtils.dpToPx
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import java.io.File
|
||||
|
||||
class SplitSelectedPdfAdapter(
|
||||
private val list: MutableList<PdfSelectedPagesItem>,
|
||||
private val onEditClick: (PdfSelectedPagesItem, Int) -> Unit,
|
||||
private val onDeleteClick: (PdfSelectedPagesItem, Int) -> Unit
|
||||
) : RecyclerView.Adapter<SplitSelectedPdfAdapter.PdfViewHolder>() {
|
||||
|
||||
inner class PdfViewHolder(val binding: AdapterSplitSelectedPageItemBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = PdfViewHolder(
|
||||
AdapterSplitSelectedPageItemBinding.inflate(
|
||||
LayoutInflater.from(parent.context), parent, false
|
||||
)
|
||||
)
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: PdfViewHolder, position: Int) {
|
||||
val item = list[position]
|
||||
holder.binding.tvPages.text = item.selectedPageNumbersString()
|
||||
val thumbPath = item.getFirstThumbPath()
|
||||
if (thumbPath.isNotEmpty()) {
|
||||
Glide.with(holder.binding.root).load(File(thumbPath))
|
||||
.transform(CenterCrop(), RoundedCorners(8.dpToPx(holder.binding.root.context)))
|
||||
.into(holder.binding.tvFileImg)
|
||||
}
|
||||
holder.binding.tvFileName.text = item.fileName
|
||||
holder.binding.editTitleBtn.setOnClickListener {
|
||||
val pos = holder.bindingAdapterPosition
|
||||
onEditClick(item, pos)
|
||||
}
|
||||
holder.binding.deleteBtn.setOnClickListener {
|
||||
val pos = holder.bindingAdapterPosition
|
||||
onDeleteClick(item, pos)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = list.size
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateAdapter() {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun updateItem(position: Int) = notifyItemChanged(position)
|
||||
|
||||
fun removeItem(position: Int) = notifyItemRemoved(position)
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
package com.all.pdfreader.pro.app.ui.dialog
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@ -125,10 +124,10 @@ class BookmarksDialogFragment(
|
||||
dialogAddBookMarks()
|
||||
}
|
||||
binding.deleteALLPageBtn.setOnClickListener {
|
||||
DeleteDialogFragment(
|
||||
PromptDialogFragment(
|
||||
getString(R.string.delete_bookmarks_title),
|
||||
getString(R.string.delete_bookmarks_desc),
|
||||
onDeleteClick = {
|
||||
onOkClick = {
|
||||
viewModel.deleteAllBookmark(pdfDocument.filePath)
|
||||
adapter.removeAllItems()
|
||||
bookmarks = emptyList()
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.all.pdfreader.pro.app.ui.dialog
|
||||
|
||||
import android.net.Uri
|
||||
import android.nfc.Tag
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@ -115,10 +114,10 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
|
||||
dismiss()
|
||||
}
|
||||
binding.deleteFileBtn.setOnClickListener {
|
||||
DeleteDialogFragment(
|
||||
PromptDialogFragment(
|
||||
getString(R.string.delete_file_title),
|
||||
getString(R.string.delete_file_desc),
|
||||
onDeleteClick = {
|
||||
onOkClick = {
|
||||
viewModel.deleteFile(pdfDocument.filePath)
|
||||
}).show(parentFragmentManager, "deleteFile")
|
||||
dismiss()
|
||||
@ -179,11 +178,11 @@ class ListMoreDialogFragment(val filePath: String) : BottomSheetDialogFragment()
|
||||
dismiss()
|
||||
}
|
||||
binding.removeRecentBtn.setOnClickListener {
|
||||
DeleteDialogFragment(
|
||||
PromptDialogFragment(
|
||||
getString(R.string.remove_dialog_title),
|
||||
getString(R.string.remove_dialog_desc),
|
||||
getString(R.string.remove),
|
||||
onDeleteClick = {
|
||||
onOkClick = {
|
||||
viewModel.removeRecent(pdfDocument.filePath)
|
||||
}).show(parentFragmentManager, "removeRecent")
|
||||
dismiss()
|
||||
|
||||
@ -11,11 +11,12 @@ import androidx.fragment.app.DialogFragment
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import com.all.pdfreader.pro.app.databinding.DialogDeleteBinding
|
||||
|
||||
class DeleteDialogFragment(
|
||||
class PromptDialogFragment(
|
||||
private val title: String,
|
||||
private val desc: String,
|
||||
private val okBtnText: String? = null,
|
||||
private val onDeleteClick: () -> Unit
|
||||
private val onOkClick: () -> Unit,
|
||||
private val onCancelClick: () -> Unit = {}
|
||||
) : DialogFragment() {
|
||||
|
||||
private lateinit var binding: DialogDeleteBinding
|
||||
@ -54,10 +55,11 @@ class DeleteDialogFragment(
|
||||
|
||||
private fun setupOnClick() {
|
||||
binding.okBtn.setOnClickListener {
|
||||
onDeleteClick()
|
||||
onOkClick()
|
||||
dismiss()
|
||||
}
|
||||
binding.cancelBtn.setOnClickListener {
|
||||
onCancelClick()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
@ -23,7 +23,9 @@ import java.io.File
|
||||
class RenameDialogFragment(
|
||||
private val type: RenameType,
|
||||
private val bookmark: BookmarkEntity? = null,
|
||||
private val onOkClick: (BookmarkEntity) -> Unit= {}
|
||||
private val name: String? = null,
|
||||
private val onOkClick: (BookmarkEntity) -> Unit = {},
|
||||
private val onOkClickString: (String) -> Unit = {}
|
||||
) : DialogFragment() {
|
||||
|
||||
private lateinit var binding: DialogRenameFileBinding
|
||||
@ -71,6 +73,15 @@ class RenameDialogFragment(
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
RenameType.NAME -> {
|
||||
name?.let {
|
||||
initView(it)
|
||||
setupOnClick(it, it, null)
|
||||
}?:run {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +115,14 @@ class RenameDialogFragment(
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
RenameType.NAME -> {
|
||||
val text = binding.etName.text.toString()
|
||||
if (validateEnter(text, oldName, filePath)) {
|
||||
onOkClickString(text)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -161,6 +180,17 @@ class RenameDialogFragment(
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
RenameType.NAME -> {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 禁止开头/结尾空格
|
||||
|
||||
@ -5,38 +5,28 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.pdf.PdfRenderer
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.CancellationSignal
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.print.PageRange
|
||||
import android.print.PrintAttributes
|
||||
import android.print.PrintDocumentAdapter
|
||||
import android.print.PrintDocumentInfo
|
||||
import android.print.PrintManager
|
||||
import android.print.pdf.PrintedPdfDocument
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.FileProvider
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.print.PrintHelper
|
||||
import com.all.pdfreader.pro.app.R
|
||||
import com.all.pdfreader.pro.app.model.PrintResult
|
||||
import com.all.pdfreader.pro.app.ui.adapter.PrintPdfAdapter
|
||||
import com.shockwave.pdfium.PdfDocument
|
||||
import com.shockwave.pdfium.PdfPasswordException
|
||||
import com.shockwave.pdfium.PdfiumCore
|
||||
import com.tom_roush.pdfbox.pdmodel.PDDocument
|
||||
import com.tom_roush.pdfbox.pdmodel.common.PDPageLabelRange
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
object AppUtils {
|
||||
|
||||
@ -326,7 +326,10 @@ object FileUtils {
|
||||
return sdf.format(Date(this))
|
||||
}
|
||||
|
||||
|
||||
fun Long.toUnderscoreDateTime(): String {
|
||||
val sdf = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH)
|
||||
return sdf.format(Date(this))
|
||||
}
|
||||
data class FileInfo(
|
||||
val name: String, val size: Long, val uri: Uri
|
||||
)
|
||||
|
||||
@ -2,8 +2,8 @@ package com.all.pdfreader.pro.app.util
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.util.Log
|
||||
import androidx.core.graphics.createBitmap
|
||||
import com.all.pdfreader.pro.app.model.PdfPageItem
|
||||
import com.shockwave.pdfium.PdfiumCore
|
||||
@ -26,7 +26,8 @@ object PdfUtils {
|
||||
fun clearPdfThumbsCache(context: Context) {
|
||||
val cacheDir = File(context.cacheDir, child)
|
||||
if (cacheDir.exists()) {
|
||||
cacheDir.listFiles()?.forEach { it.delete() }
|
||||
val ss = cacheDir.deleteRecursively() // Kotlin 提供的递归删除方法
|
||||
Log.d("ocean", "clearPdfThumbsCache->$ss")
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,13 +67,10 @@ object PdfUtils {
|
||||
val targetHeight = (height * scale).toInt()
|
||||
|
||||
val bitmap = createBitmap(thumbWidth, targetHeight, Bitmap.Config.RGB_565)
|
||||
val canvas = Canvas(bitmap)
|
||||
canvas.scale(scale, scale)
|
||||
|
||||
pdfiumCore.renderPageBitmap(pdfDocument, bitmap, i, 0, 0, width, height)
|
||||
pdfiumCore.renderPageBitmap(pdfDocument, bitmap, i, 0, 0, thumbWidth, targetHeight)
|
||||
|
||||
// 保存为压缩 JPEG
|
||||
val outFile = File(cacheDir, "page_$i.jpg")
|
||||
val outFile = File(cacheDir, inputFile.name + "_page_$i.jpg")
|
||||
FileOutputStream(outFile).use { fos ->
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos)
|
||||
}
|
||||
@ -89,36 +87,45 @@ object PdfUtils {
|
||||
}.flowOn(Dispatchers.IO)
|
||||
|
||||
/**
|
||||
* 获取 PDF 总页数
|
||||
*/
|
||||
fun getPdfPageCount(inputFile: File): Int {
|
||||
PDDocument.load(inputFile).use { return it.numberOfPages }
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出用户勾选的页生成新的 PDF
|
||||
* 导出选中的 PDF 页到一个新的 PDF 文件
|
||||
*
|
||||
* 使用 PDFBox 的 PDDocument 导出原 PDF 中选中的页,支持进度回调。
|
||||
* 避免直接使用缩略图生成 PDF,以保持原 PDF 的矢量质量。
|
||||
*
|
||||
* @param inputFile 原 PDF 文件
|
||||
* @param selectedPages 用户选择的页列表
|
||||
* @param outputDir 输出目录(外部存储可访问目录)
|
||||
* @param outputFileName 输出文件名
|
||||
* @param selectedPages 选中的页对象列表,每个对象包含 pageIndex
|
||||
* @param outputDir 输出目录,如果不存在会自动创建
|
||||
* @param outputFileName 输出文件名,例如 "selected.pdf"
|
||||
* @param onProgress 可选回调,当前处理进度 (current 页, total 页)
|
||||
* @return 新生成的 PDF 文件,失败返回 null
|
||||
*/
|
||||
suspend fun exportSelectedPages(
|
||||
inputFile: File, selectedPages: List<PdfPageItem>, outputDir: File, outputFileName: String
|
||||
inputFile: File,
|
||||
selectedPages: List<PdfPageItem>,
|
||||
outputDir: File,
|
||||
outputFileName: String,
|
||||
onProgress: ((current: Int, total: Int) -> Unit)? = null
|
||||
): File? = withContext(Dispatchers.IO) {
|
||||
|
||||
// 如果没有选中的页,直接返回 null
|
||||
if (selectedPages.isEmpty()) return@withContext null
|
||||
|
||||
if (!outputDir.exists()) outputDir.mkdirs() // 确保目录存在
|
||||
|
||||
if (!outputDir.exists()) outputDir.mkdirs()
|
||||
val outputFile = File(outputDir, outputFileName)
|
||||
try {
|
||||
PDDocument.load(inputFile).use { document ->
|
||||
val newDocument = PDDocument()
|
||||
selectedPages.sortedBy { it.pageIndex }.forEach { pageItem ->
|
||||
val page = document.getPage(pageItem.pageIndex)
|
||||
newDocument.addPage(page)
|
||||
PDDocument().use { newDocument ->
|
||||
// 按页索引排序,保证顺序正确
|
||||
val sortedPages = selectedPages.sortedBy { it.pageIndex }
|
||||
val total = sortedPages.size//总数
|
||||
sortedPages.forEachIndexed { index, pageItem ->
|
||||
// 导入原文档的页面到新文档
|
||||
newDocument.importPage(document.getPage(pageItem.pageIndex))
|
||||
// 回调进度
|
||||
onProgress?.invoke(index + 1, total)
|
||||
}
|
||||
// 保存新 PDF 文件
|
||||
newDocument.save(outputFile)
|
||||
newDocument.close()
|
||||
}
|
||||
}
|
||||
outputFile
|
||||
} catch (e: Exception) {
|
||||
@ -126,4 +133,5 @@ object PdfUtils {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,6 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="8dp"/>
|
||||
<solid android:color="@color/grey"/>
|
||||
<solid android:color="@color/placeholder_bg_color"/>
|
||||
|
||||
</shape>
|
||||
15
app/src/main/res/drawable/underline_dashed.xml
Normal file
15
app/src/main/res/drawable/underline_dashed.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 底部的虚线 -->
|
||||
<item
|
||||
android:gravity="bottom"
|
||||
android:height="2dp">
|
||||
<shape android:shape="line">
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/line_color"
|
||||
android:dashWidth="6dp"
|
||||
android:dashGap="3dp" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@ -62,6 +62,25 @@
|
||||
android:src="@drawable/gou_white" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/addBtn"
|
||||
android:layout_width="44dp"
|
||||
android:layout_height="44dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/addAll"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:background="@drawable/dr_circular_sel_on_bg"
|
||||
android:padding="2dp"
|
||||
android:src="@drawable/add_icon_white" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include
|
||||
@ -70,13 +89,16 @@
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/splitListLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="visible">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/splitRv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/continue_now_btn"
|
||||
android:layout_margin="8dp"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none"
|
||||
@ -86,11 +108,14 @@
|
||||
tools:listitem="@layout/adapter_split_page_item" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/allow_access_btn"
|
||||
android:id="@+id/continue_now_btn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_margin="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/dr_btn_not_clickable_bg"
|
||||
android:gravity="center">
|
||||
|
||||
@ -103,4 +128,43 @@
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/splitSelectLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/splitSelectRv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/splitBtn"
|
||||
android:layout_margin="8dp"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/adapter_split_selected_page_item" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/splitBtn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/dr_btn_not_clickable_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
style="@style/TextViewFont_PopSemiBold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/split_pdf"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
133
app/src/main/res/layout/activity_pdf_split_result.xml
Normal file
133
app/src/main/res/layout/activity_pdf_split_result.xml
Normal file
@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/bg_color"
|
||||
android:orientation="vertical">
|
||||
|
||||
<View
|
||||
android:id="@+id/view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/statusLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/backBtn"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/back_black" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/dr_circular_sel_on_bg"
|
||||
android:src="@drawable/gou_white" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextViewFont_PopMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/congratulations"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextViewFont_PopMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/file_created_success"
|
||||
android:textColor="@color/black_60"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_margin="16dp"
|
||||
android:background="@color/line_color" />
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
android:layout_margin="16dp"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/adapter_split_selected_result_item" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/shareBtn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/dr_cancel_btn_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
style="@style/TextViewFont_PopSemiBold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/share_file"
|
||||
android:textColor="@color/black_60"
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/okBtn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/dr_click_btn_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/okBtnTv"
|
||||
style="@style/TextViewFont_PopSemiBold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ok"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@ -19,11 +19,23 @@
|
||||
android:layout_height="56dp"
|
||||
android:background="@drawable/dr_item_img_frame">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/dr_placeholder_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:src="@drawable/file_document" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tvFileImg"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:src="@mipmap/ic_launcher_round" />
|
||||
android:layout_height="56dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:visibility="gone"
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<RelativeLayout
|
||||
android:id="@+id/itemBgLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="230dp"
|
||||
android:layout_height="220dp"
|
||||
android:layout_margin="8dp"
|
||||
android:background="@drawable/dr_sel_off_frame"
|
||||
android:gravity="center"
|
||||
@ -28,8 +28,7 @@
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pageNumberTv"
|
||||
|
||||
140
app/src/main/res/layout/adapter_split_selected_page_item.xml
Normal file
140
app/src/main/res/layout/adapter_split_selected_page_item.xml
Normal file
@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingTop="8dp"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:background="@drawable/dr_item_img_frame">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/dr_placeholder_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:src="@drawable/file_document" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tvFileImg"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/editTitleBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFileName"
|
||||
style="@style/TextViewFont_PopMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="middle"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/icon_color"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:src="@drawable/edit_icon" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:background="@drawable/underline_dashed" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
style="@style/TextViewFont_PopRegular"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/pages"
|
||||
android:textColor="@color/black_60"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPages"
|
||||
style="@style/TextViewFont_PopRegular"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="0"
|
||||
android:textColor="@color/black_60"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/deleteBtn"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/delete_cha_icon" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@color/line_color" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingTop="8dp"
|
||||
tools:ignore="RtlSymmetry">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:background="@drawable/dr_item_img_frame">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/dr_placeholder_bg"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:src="@drawable/file_document" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/nameTv"
|
||||
style="@style/TextViewFont_PopMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="middle"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/icon_color"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pathTv"
|
||||
style="@style/TextViewFont_PopRegular"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:text="@string/path_details"
|
||||
android:textColor="@color/black_60"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/selectBtn"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/selectIv"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/gou" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@color/line_color" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -18,6 +18,7 @@
|
||||
<string name="sort_by">Sort by</string>
|
||||
<string name="created_date">Created Date</string>
|
||||
<string name="path">Path</string>
|
||||
<string name="path_details">Path %1$s</string>
|
||||
<string name="file_name">File Name</string>
|
||||
<string name="file_size">File Size</string>
|
||||
<string name="ascending">Ascending</string>
|
||||
@ -120,8 +121,16 @@
|
||||
<string name="bookmark_loading">Loading bookmarks, please try again later</string>
|
||||
<string name="no_files_yet">no files yet</string>
|
||||
<string name="split_pdf">Split PDF</string>
|
||||
<string name="split">Split</string>
|
||||
<string name="merge_pdf">Merge PDF</string>
|
||||
<string name="selected_page">%1$d Selected</string>
|
||||
<string name="loading">Loading</string>
|
||||
<string name="continue_now">Continue Now</string>
|
||||
<string name="exit_split">Exit Split</string>
|
||||
<string name="confirm_discard_changes">Are you sure you want to exit and discard changes?</string>
|
||||
<string name="discard">Discard</string>
|
||||
<string name="pages">Pages:</string>
|
||||
<string name="congratulations">Congratulations</string>
|
||||
<string name="file_created_success">Your file has been successfully created</string>
|
||||
<string name="please_select_page">Please select at least one page</string>
|
||||
</resources>
|
||||
Loading…
Reference in New Issue
Block a user