Kotlin安卓:如何通过RecyclerView打开Assets中的PDF文件
实现步骤
1. 修改Parcelable数据类
原来的数据类可以精简,只保留列表展示和搜索需要的标题,以及对应Assets中PDF的文件名即可:
import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize data class PdfItem( val title: String, // 列表展示、搜索用的标题 val pdfFileName: String // 对应Assets里的PDF文件名,比如"pr1.pdf" ) : Parcelable
2. 更新RecyclerView数据源
把原列表数据替换成包含标题和对应PDF文件名的PdfItem集合:
val pdfItemList = listOf( PdfItem("项目报告1", "pr1.pdf"), PdfItem("项目报告2", "pr2.pdf"), // 依次添加到pr30.pdf的对应项 )
3. 处理列表点击打开Assets中的PDF
Assets里的文件无法直接通过路径打开,需要先复制到应用临时目录,再用你已掌握的本地PDF打开方式调用:
第一步:写个工具函数复制Assets文件到临时目录
import android.content.Context import java.io.File import java.io.FileOutputStream import java.io.InputStream fun copyAssetToTemp(context: Context, assetName: String): File? { return try { // 打开Assets中的文件流 val inputStream = context.assets.open(assetName) // 创建临时文件(存在应用缓存目录) val tempFile = File(context.cacheDir, assetName) // 复制文件内容 val outputStream = FileOutputStream(tempFile) inputStream.copyTo(outputStream) // 关闭流 inputStream.close() outputStream.close() tempFile } catch (e: Exception) { e.printStackTrace() null } }
第二步:在RecyclerView点击事件中调用
在Adapter的onBindViewHolder里替换原点击逻辑:
holder.itemView.setOnClickListener { val currentItem = pdfItemList[position] // 复制Assets文件到临时目录 val tempPdfFile = copyAssetToTemp(context, currentItem.pdfFileName) tempPdfFile?.let { file -> // 这里用你已掌握的本地PDF打开代码,示例用Intent调用系统PDF阅读器 val intent = Intent(Intent.ACTION_VIEW) // 注意Android 7.0+必须用FileProvider获取Uri val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file) intent.setDataAndType(uri, "application/pdf") intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) context.startActivity(intent) } }
第三步:配置FileProvider(Android 7.0+必需)
在AndroidManifest.xml的<application>标签内添加:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
然后在res/xml目录下创建file_paths.xml文件:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="cache_pdfs" path="." /> </paths>
4. 保留SearchView搜索功能
原搜索逻辑只需针对PdfItem的title字段过滤即可,无需大改:
// 示例过滤函数 fun filterPdfList(query: String): List<PdfItem> { return pdfItemList.filter { it.title.contains(query, ignoreCase = true) } }
过滤后将新列表传给Adapter更新即可。
关键注意事项
- Assets目录下的PDF文件名必须和数据类中的
pdfFileName完全一致(区分大小写) - 复制文件时要捕获异常,避免因文件不存在或IO错误导致崩溃
- 不要忘记配置FileProvider,否则Android 7.0+会出现权限拒绝问题
内容的提问来源于stack exchange,提问作者Katarizi
相关产品推荐
相关产品推荐

