修复搜索的时候,需要密码来加载。
This commit is contained in:
parent
ed7430e7d2
commit
e93d08b56f
@ -1,226 +0,0 @@
|
|||||||
package com.all.pdfreader.pro.app.ui.act
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import com.all.pdfreader.pro.app.databinding.ActivityPdfViewerTestBinding
|
|
||||||
import com.all.pdfreader.pro.app.ui.adapter.SearchResultsAdapter
|
|
||||||
import com.all.pdfreader.pro.app.util.PDFHighlighter
|
|
||||||
import com.all.pdfreader.pro.app.util.PDFSearchManager
|
|
||||||
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener
|
|
||||||
import com.tom_roush.pdfbox.pdmodel.PDDocument
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class PdfTextSearchTestActivity : BaseActivity() {
|
|
||||||
override val TAG: String = "PdfTextSearchTestActivity"
|
|
||||||
private lateinit var binding: ActivityPdfViewerTestBinding
|
|
||||||
private lateinit var searchManager: PDFSearchManager
|
|
||||||
private lateinit var highlighter: PDFHighlighter
|
|
||||||
|
|
||||||
private var pdfFile: File? = null
|
|
||||||
private val searchResults = mutableListOf<PDFSearchManager.TextSearchResult>()
|
|
||||||
private lateinit var adapter: SearchResultsAdapter
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
binding = ActivityPdfViewerTestBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
val pdfPath = intent.getStringExtra("pdf_path") ?: ""
|
|
||||||
if (pdfPath.isEmpty()) {
|
|
||||||
finish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pdfFile = File(pdfPath)
|
|
||||||
initViews()
|
|
||||||
setupPDFViewer()
|
|
||||||
loadPDF()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initViews() {
|
|
||||||
adapter = SearchResultsAdapter(searchResults) { result ->
|
|
||||||
onSearchResultClicked(result, true)
|
|
||||||
}
|
|
||||||
binding.searchResultsRecyclerView.adapter = adapter
|
|
||||||
binding.searchResultsRecyclerView.layoutManager = LinearLayoutManager(this)
|
|
||||||
|
|
||||||
binding.searchButton.alpha = 0.5f
|
|
||||||
binding.searchButton.isEnabled = false
|
|
||||||
binding.searchButton.setOnClickListener {
|
|
||||||
performSearch()
|
|
||||||
}
|
|
||||||
binding.clearButton.setOnClickListener {
|
|
||||||
clearHighlights()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupPDFViewer() {
|
|
||||||
searchManager = PDFSearchManager(binding.pdfView)
|
|
||||||
highlighter = PDFHighlighter(binding.pdfView, searchManager)
|
|
||||||
|
|
||||||
initSearchDocument()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initSearchDocument() {
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
searchManager.getDocument(
|
|
||||||
pdfFile!!,
|
|
||||||
onLoaded = { doc ->
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
checkPageHasText(doc, binding.pdfView.currentPage)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onError = { e ->
|
|
||||||
runOnUiThread {
|
|
||||||
binding.searchButton.alpha = 0.5f
|
|
||||||
binding.searchButton.isEnabled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 异步检查指定页是否有文字并更新按钮
|
|
||||||
*/
|
|
||||||
private suspend fun checkPageHasText(doc: PDDocument, pageIndex: Int): Boolean {
|
|
||||||
val hasText = searchManager.pageHasText(doc, pageIndex, minChars = 8) // 可调整阈值
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
if (hasText) {
|
|
||||||
binding.searchButton.alpha = 1f
|
|
||||||
binding.searchButton.isEnabled = true
|
|
||||||
} else {
|
|
||||||
binding.searchButton.alpha = 0.5f
|
|
||||||
binding.searchButton.isEnabled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hasText
|
|
||||||
}
|
|
||||||
|
|
||||||
private var pageCheckJob: Job? = null
|
|
||||||
|
|
||||||
private fun loadPDF() {
|
|
||||||
binding.pdfView.fromFile(pdfFile)
|
|
||||||
.enableSwipe(true)
|
|
||||||
.swipeHorizontal(true)
|
|
||||||
.enableDoubletap(true)
|
|
||||||
.defaultPage(0)
|
|
||||||
.onDraw(highlighter) // 设置绘制监听器
|
|
||||||
.enableAnnotationRendering(true)
|
|
||||||
.password(null)
|
|
||||||
.scrollHandle(null)
|
|
||||||
.swipeHorizontal(false)
|
|
||||||
.enableAntialiasing(true)
|
|
||||||
.onPageChange(object : OnPageChangeListener {
|
|
||||||
override fun onPageChanged(page: Int, pageCount: Int) {
|
|
||||||
logDebug("page->$page")
|
|
||||||
logDebug("pageCount->$pageCount")
|
|
||||||
val doc = searchManager.getCachedDoc()
|
|
||||||
if (doc != null) {
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
pageCheckJob?.cancel()
|
|
||||||
pageCheckJob = lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
delay(50) // 防抖
|
|
||||||
val hasText = checkPageHasText(doc, page)
|
|
||||||
//确定这页有文字,是否进行搜索过,当前搜索的文字
|
|
||||||
if (hasText && searchManager.hasSearched && searchManager.currentSearchText != null) {
|
|
||||||
searchTextIng(
|
|
||||||
pdfFile!!,
|
|
||||||
searchManager.currentSearchText ?: "",
|
|
||||||
binding.pdfView.currentPage
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.spacing(0)
|
|
||||||
.load()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun performSearch() {
|
|
||||||
val searchText = binding.searchEditText.text.toString().trim()
|
|
||||||
if (searchText.isEmpty()) {
|
|
||||||
Toast.makeText(this, "请输入搜索关键词", Toast.LENGTH_SHORT).show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val file = pdfFile ?: return
|
|
||||||
|
|
||||||
binding.progressBar.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
searchTextIng(file, searchText, binding.pdfView.currentPage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun searchTextIng(pdfFile: File, key: String, targetPage: Int? = null) {
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
try {
|
|
||||||
val results = searchManager.searchText(pdfFile, key, targetPage)
|
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
binding.progressBar.visibility = View.GONE
|
|
||||||
searchResults.clear()
|
|
||||||
searchResults.addAll(results)
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
|
|
||||||
if (!results.isEmpty()) {
|
|
||||||
results.firstOrNull()?.let { firstResult ->
|
|
||||||
onSearchResultClicked(firstResult)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
binding.progressBar.visibility = View.GONE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onSearchResultClicked(
|
|
||||||
result: PDFSearchManager.TextSearchResult,
|
|
||||||
isJumpTo: Boolean = false
|
|
||||||
) {
|
|
||||||
if (isJumpTo) {
|
|
||||||
// 跳转到对应页面 (PDFView 页面索引从0开始)
|
|
||||||
binding.pdfView.jumpTo(result.pageNumber - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置高亮
|
|
||||||
highlighter.setCurrentPageHighlights(result.pageNumber)
|
|
||||||
|
|
||||||
// 标记已搜索高亮
|
|
||||||
searchManager.currentSearchText = result.text
|
|
||||||
searchManager.hasSearched = true
|
|
||||||
|
|
||||||
// 可选:滚动到搜索结果列表中的对应项
|
|
||||||
val index = searchResults.indexOf(result)
|
|
||||||
if (index != -1) {
|
|
||||||
binding.searchResultsRecyclerView.scrollToPosition(index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun clearHighlights() {
|
|
||||||
searchManager.clearHighlights()
|
|
||||||
highlighter.clearCurrentHighlights()
|
|
||||||
searchResults.clear()
|
|
||||||
adapter.notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
searchManager.closeCachedDocument()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -71,6 +71,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
|||||||
private lateinit var searchManager: PDFSearchManager
|
private lateinit var searchManager: PDFSearchManager
|
||||||
private lateinit var highlighter: PDFHighlighter
|
private lateinit var highlighter: PDFHighlighter
|
||||||
private var pageCheckJob: Job? = null
|
private var pageCheckJob: Job? = null
|
||||||
|
private var currentPassword: String? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -269,7 +270,6 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
|||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setupPDFSearchManager()//初始化搜索文本需要的类
|
|
||||||
if (pdfDocument.isPassword) {
|
if (pdfDocument.isPassword) {
|
||||||
showPasswordDialog(file)
|
showPasswordDialog(file)
|
||||||
} else {
|
} else {
|
||||||
@ -316,6 +316,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
|||||||
pageCheckJob?.cancel()
|
pageCheckJob?.cancel()
|
||||||
// 启动新的防抖任务
|
// 启动新的防抖任务
|
||||||
pageCheckJob = lifecycleScope.launch(Dispatchers.IO) {
|
pageCheckJob = lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
highlighter.clearCurrentHighlights()//新的之前先清除
|
||||||
delay(120) // 防抖 120ms
|
delay(120) // 防抖 120ms
|
||||||
val hasText = checkPageHasText(doc, page)
|
val hasText = checkPageHasText(doc, page)
|
||||||
if (hasText && searchManager.hasSearched && !searchManager.currentSearchText.isNullOrEmpty()) {
|
if (hasText && searchManager.hasSearched && !searchManager.currentSearchText.isNullOrEmpty()) {
|
||||||
@ -339,6 +340,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
|||||||
private fun showPasswordDialog(file: File) {
|
private fun showPasswordDialog(file: File) {
|
||||||
PdfPasswordProtectionDialogFragment(file, onOkClick = { password ->
|
PdfPasswordProtectionDialogFragment(file, onOkClick = { password ->
|
||||||
tryLoadPdfWithPassword(file, password)
|
tryLoadPdfWithPassword(file, password)
|
||||||
|
currentPassword = password
|
||||||
}, onCancelClick = {
|
}, onCancelClick = {
|
||||||
finish()
|
finish()
|
||||||
}).show(supportFragmentManager, TAG)
|
}).show(supportFragmentManager, TAG)
|
||||||
@ -349,6 +351,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadPdfInternal(file: File, password: String?) {
|
private fun loadPdfInternal(file: File, password: String?) {
|
||||||
|
setupPDFSearchManager(password)//初始化搜索文本需要的类
|
||||||
binding.pdfview.fromFile(file).apply {
|
binding.pdfview.fromFile(file).apply {
|
||||||
password?.let { password(it) } // 只有在有密码时才调用
|
password?.let { password(it) } // 只有在有密码时才调用
|
||||||
defaultPage(pdfDocument.lastReadPage) // 从上次阅读页码开始
|
defaultPage(pdfDocument.lastReadPage) // 从上次阅读页码开始
|
||||||
@ -454,17 +457,17 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupPDFSearchManager() {
|
private fun setupPDFSearchManager(password: String?) {
|
||||||
searchManager = PDFSearchManager(binding.pdfview)
|
searchManager = PDFSearchManager(binding.pdfview)
|
||||||
highlighter = PDFHighlighter(binding.pdfview, searchManager)
|
highlighter = PDFHighlighter(binding.pdfview, searchManager)
|
||||||
|
|
||||||
initSearchDocument()
|
initSearchDocument(password)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initSearchDocument() {
|
private fun initSearchDocument(password: String?) {
|
||||||
val file = File(pdfDocument.filePath)
|
val file = File(pdfDocument.filePath)
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
searchManager.getDocument(file, onLoaded = { doc ->
|
searchManager.getDocument(file, password, onLoaded = { doc ->
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
checkPageHasText(doc, binding.pdfview.currentPage)
|
checkPageHasText(doc, binding.pdfview.currentPage)
|
||||||
}
|
}
|
||||||
@ -504,7 +507,7 @@ class PdfViewActivity : BaseActivity(), OnLoadCompleteListener, OnPageChangeList
|
|||||||
private fun searchTextIng(pdfFile: File, key: String, targetPage: Int? = null) {
|
private fun searchTextIng(pdfFile: File, key: String, targetPage: Int? = null) {
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val results = searchManager.searchText(pdfFile, key, targetPage)
|
val results = searchManager.searchText(pdfFile, key, targetPage, currentPassword)
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (!results.isEmpty()) {
|
if (!results.isEmpty()) {
|
||||||
|
|||||||
@ -1,41 +0,0 @@
|
|||||||
package com.all.pdfreader.pro.app.ui.adapter
|
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.all.pdfreader.pro.app.R
|
|
||||||
import com.all.pdfreader.pro.app.util.PDFSearchManager
|
|
||||||
|
|
||||||
class SearchResultsAdapter(
|
|
||||||
private val results: List<PDFSearchManager.TextSearchResult>,
|
|
||||||
private val onItemClick: (PDFSearchManager.TextSearchResult) -> Unit
|
|
||||||
) : RecyclerView.Adapter<SearchResultsAdapter.ViewHolder>() {
|
|
||||||
|
|
||||||
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
|
||||||
val pageText: TextView = view.findViewById(R.id.pageText)
|
|
||||||
val matchCount: TextView = view.findViewById(R.id.matchCount)
|
|
||||||
val previewText: TextView = view.findViewById(R.id.previewText)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
|
||||||
val view = LayoutInflater.from(parent.context)
|
|
||||||
.inflate(R.layout.item_search_result, parent, false)
|
|
||||||
return ViewHolder(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
|
||||||
val result = results[position]
|
|
||||||
|
|
||||||
holder.pageText.text = "第 ${result.pageNumber} 页"
|
|
||||||
holder.matchCount.text = "${result.positions.size} 处匹配"
|
|
||||||
holder.previewText.text = "搜索: \"${result.text}\""
|
|
||||||
|
|
||||||
holder.itemView.setOnClickListener {
|
|
||||||
onItemClick(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getItemCount() = results.size
|
|
||||||
}
|
|
||||||
@ -14,7 +14,6 @@ import com.all.pdfreader.pro.app.model.SortConfig
|
|||||||
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
import com.all.pdfreader.pro.app.room.entity.PdfDocumentEntity
|
||||||
import com.all.pdfreader.pro.app.room.repository.PdfRepository
|
import com.all.pdfreader.pro.app.room.repository.PdfRepository
|
||||||
import com.all.pdfreader.pro.app.ui.act.MainActivity
|
import com.all.pdfreader.pro.app.ui.act.MainActivity
|
||||||
import com.all.pdfreader.pro.app.ui.act.PdfTextSearchTestActivity
|
|
||||||
import com.all.pdfreader.pro.app.ui.act.PdfViewActivity
|
import com.all.pdfreader.pro.app.ui.act.PdfViewActivity
|
||||||
import com.all.pdfreader.pro.app.ui.adapter.PdfAdapter
|
import com.all.pdfreader.pro.app.ui.adapter.PdfAdapter
|
||||||
import com.all.pdfreader.pro.app.ui.dialog.ListMoreDialogFragment
|
import com.all.pdfreader.pro.app.ui.dialog.ListMoreDialogFragment
|
||||||
|
|||||||
@ -67,6 +67,7 @@ class PDFSearchManager(private val pdfView: PDFView) {
|
|||||||
*/
|
*/
|
||||||
fun getDocument(
|
fun getDocument(
|
||||||
file: File,
|
file: File,
|
||||||
|
password: String?,
|
||||||
onLoaded: ((PDDocument) -> Unit)? = null,
|
onLoaded: ((PDDocument) -> Unit)? = null,
|
||||||
onError: ((Exception) -> Unit)? = null
|
onError: ((Exception) -> Unit)? = null
|
||||||
): PDDocument {
|
): PDDocument {
|
||||||
@ -74,7 +75,11 @@ class PDFSearchManager(private val pdfView: PDFView) {
|
|||||||
try {
|
try {
|
||||||
// 如果是新的文件,则关闭旧文档
|
// 如果是新的文件,则关闭旧文档
|
||||||
cachedDoc?.close()
|
cachedDoc?.close()
|
||||||
cachedDoc = PDDocument.load(file)
|
cachedDoc = if (!password.isNullOrEmpty()) {
|
||||||
|
PDDocument.load(file, password)
|
||||||
|
} else {
|
||||||
|
PDDocument.load(file)
|
||||||
|
}
|
||||||
cachedPath = file.absolutePath
|
cachedPath = file.absolutePath
|
||||||
|
|
||||||
// 通知加载成功
|
// 通知加载成功
|
||||||
@ -114,14 +119,19 @@ class PDFSearchManager(private val pdfView: PDFView) {
|
|||||||
* @param key 搜索关键词
|
* @param key 搜索关键词
|
||||||
* @param targetPage 可选参数:指定页码(从 0 开始)。如果为 null 则搜索整本。
|
* @param targetPage 可选参数:指定页码(从 0 开始)。如果为 null 则搜索整本。
|
||||||
*/
|
*/
|
||||||
fun searchText(pdfFile: File, key: String, targetPage: Int? = null): List<TextSearchResult> {
|
fun searchText(pdfFile: File, key: String, targetPage: Int? = null,password: String?): List<TextSearchResult> {
|
||||||
Log.d("ocean", "searchText pdfFile->$pdfFile")
|
Log.d("ocean", "searchText pdfFile->$pdfFile")
|
||||||
Log.d("ocean", "searchText key->$key")
|
Log.d("ocean", "searchText key->$key")
|
||||||
Log.d("ocean", "searchText targetPage->$targetPage")
|
Log.d("ocean", "searchText targetPage->$targetPage")
|
||||||
val results = mutableListOf<TextSearchResult>()
|
val results = mutableListOf<TextSearchResult>()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val doc = getDocument(pdfFile) // 这里不再每次重新 load
|
// 这里不再每次重新 load
|
||||||
|
val doc = if (!password.isNullOrEmpty()) {
|
||||||
|
PDDocument.load(pdfFile, password)
|
||||||
|
} else {
|
||||||
|
PDDocument.load(pdfFile)
|
||||||
|
}
|
||||||
|
|
||||||
val startPage = targetPage ?: 0
|
val startPage = targetPage ?: 0
|
||||||
val endPage = targetPage ?: (doc.numberOfPages - 1)
|
val endPage = targetPage ?: (doc.numberOfPages - 1)
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
android:id="@+id/sidebarBtn"
|
android:id="@+id/sidebarBtn"
|
||||||
android:layout_width="44dp"
|
android:layout_width="44dp"
|
||||||
android:layout_height="44dp"
|
android:layout_height="44dp"
|
||||||
|
android:visibility="gone"
|
||||||
android:layout_marginStart="6dp"
|
android:layout_marginStart="6dp"
|
||||||
android:background="@drawable/dr_click_effect_oval_transparent"
|
android:background="@drawable/dr_click_effect_oval_transparent"
|
||||||
android:gravity="center">
|
android:gravity="center">
|
||||||
@ -36,7 +37,7 @@
|
|||||||
style="@style/TextViewFont_PopMedium"
|
style="@style/TextViewFont_PopMedium"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="6dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="6dp"
|
android:layout_marginEnd="6dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/app_name"
|
android:text="@string/app_name"
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<!-- 搜索栏 -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="#f5f5f5"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:padding="8dp">
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/searchEditText"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:hint="输入搜索关键词"
|
|
||||||
android:imeOptions="actionSearch"
|
|
||||||
android:singleLine="true" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/searchButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:text="搜索" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/clearButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:text="清除" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/debugTextView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progressBar"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<!-- PDF显示区域 -->
|
|
||||||
<com.github.barteksc.pdfviewer.PDFView
|
|
||||||
android:id="@+id/pdfView"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="3" />
|
|
||||||
|
|
||||||
<!-- 搜索结果列表 -->
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/searchResultsRecyclerView"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:background="#ffffff" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
Loading…
Reference in New Issue
Block a user