Android PDF阅读器开发:实现History Fragment与Document Fragment间PDF阅读页码双向同步
我来帮你解决这个PDF页码双向同步的问题,核心问题出在你当前的页码存储逻辑上——现在的实现既做不到跨Activity共享数据,也没有区分不同的PDF文件,自然无法实现双向同步。
问题根源分析
- SharedPreferences作用域错误:你用的
getPreferences(MODE_PRIVATE)是当前Activity的私有存储,ViewPdf和ViewHistoryPdf的存储完全独立,两边的页码数据根本互通不了。 - 未区分不同PDF文件:所有PDF的页码都存在同一个
"page"键下,打开不同PDF时会互相覆盖,导致页码混乱。
解决方案步骤
我们需要做两个核心修改:用全局SharedPreferences统一存储所有PDF的阅读进度,并且用PDF文件的绝对路径作为每个文件的唯一标识,确保不同PDF的页码不会互相干扰。同时要保证页面离开时自动保存当前页码。
修改后的代码实现
1. 更新ViewPdf.java
public class ViewPdf extends AppCompatActivity { public static PDFView pdfView; TextView textView; File currentPdfFile; SharedPreferences pageRecordsPrefs; SharedPreferences.Editor editor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_pdf); pdfView = findViewById(R.id.pdfView); textView = findViewById(R.id.pagenumber); // 全局SharedPreferences,所有Activity共享 pageRecordsPrefs = getSharedPreferences("PDF_PAGE_RECORDS", MODE_PRIVATE); editor = pageRecordsPrefs.edit(); // 获取要打开的PDF文件 int position = getIntent().getIntExtra("Position", -1); if (position != -1) { currentPdfFile = DocumentsFragment.pdf.get(position); loadPdfWithSavedPage(currentPdfFile); } } private void loadPdfWithSavedPage(File pdfFile) { // 用文件绝对路径作为唯一键,默认加载第0页(第一页) String pageKey = "page_" + pdfFile.getAbsolutePath(); int savedPage = pageRecordsPrefs.getInt(pageKey, 0); pdfView.fromFile(pdfFile) .enableAnnotationRendering(true) .defaultPage(savedPage) .swipeHorizontal(true) .nightMode(true) .fitEachPage(true) .onPageChange((page, pageCount) -> { textView.setText(String.valueOf(page + 1) + "/" + pageCount); // 实时保存页码(也可以在onPause时统一保存) editor.putInt(pageKey, page); editor.apply(); }) .pageSnap(true) .pageFling(true) .autoSpacing(false) .spacing(12) .enableAntialiasing(true) .pageFitPolicy(FitPolicy.BOTH) .load(); } @Override protected void onPause() { super.onPause(); // 页面离开时再次确认保存,防止实时保存遗漏 if (currentPdfFile != null && pdfView != null) { String pageKey = "page_" + currentPdfFile.getAbsolutePath(); editor.putInt(pageKey, pdfView.getCurrentPage()); editor.apply(); } } }
2. 更新ViewHistoryPdf.java
public class ViewHistoryPdf extends AppCompatActivity { PDFView pdfView; TextView textView; File currentPdfFile; SharedPreferences pageRecordsPrefs; SharedPreferences.Editor editor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_pdf); pdfView = findViewById(R.id.pdfView); textView = findViewById(R.id.pagenumber); // 和ViewPdf用同一个全局SharedPreferences pageRecordsPrefs = getSharedPreferences("PDF_PAGE_RECORDS", MODE_PRIVATE); editor = pageRecordsPrefs.edit(); // 获取要打开的历史PDF文件 int historyPosition = getIntent().getIntExtra("History", -1); if (historyPosition != -1) { currentPdfFile = HistoryFragment.pdfHistory.get(historyPosition); loadPdfWithSavedPage(currentPdfFile); } } private void loadPdfWithSavedPage(File pdfFile) { String pageKey = "page_" + pdfFile.getAbsolutePath(); int savedPage = pageRecordsPrefs.getInt(pageKey, 0); pdfView.fromFile(pdfFile) .enableAnnotationRendering(true) .defaultPage(savedPage) .swipeHorizontal(true) .nightMode(true) .fitEachPage(true) .onPageChange((page, pageCount) -> { textView.setText(String.valueOf(page + 1) + "/" + pageCount); editor.putInt(pageKey, page); editor.apply(); }) .pageSnap(true) .pageFling(true) .autoSpacing(false) .spacing(12) .enableAntialiasing(true) .pageFitPolicy(FitPolicy.BOTH) .load(); } @Override protected void onPause() { super.onPause(); if (currentPdfFile != null && pdfView != null) { String pageKey = "page_" + currentPdfFile.getAbsolutePath(); editor.putInt(pageKey, pdfView.getCurrentPage()); editor.apply(); } } }
额外优化建议
为了避免代码重复,你可以把PDF加载和页码处理的逻辑抽成工具类,比如:
public class PdfViewerHelper { public static void loadPdf(PDFView pdfView, File pdfFile, TextView pageText, SharedPreferences prefs) { String pageKey = "page_" + pdfFile.getAbsolutePath(); int savedPage = prefs.getInt(pageKey, 0); SharedPreferences.Editor editor = prefs.edit(); pdfView.fromFile(pdfFile) .enableAnnotationRendering(true) .defaultPage(savedPage) .swipeHorizontal(true) .nightMode(true) .fitEachPage(true) .onPageChange((page, pageCount) -> { pageText.setText(String.valueOf(page + 1) + "/" + pageCount); editor.putInt(pageKey, page); editor.apply(); }) .pageSnap(true) .pageFling(true) .autoSpacing(false) .spacing(12) .enableAntialiasing(true) .pageFitPolicy(FitPolicy.BOTH) .load(); } }
这样两个Activity里只需要一行代码就能完成PDF加载,代码会更简洁易维护。
内容的提问来源于stack exchange,提问作者Knowledge hub
相关产品推荐
相关产品推荐

