Android Studio中Fragment打印HTML文档的正确实现方案咨询
解决Android Fragment中WebView打印无响应及ANR问题
咱们先从你代码里的核心问题入手——这也是按钮无响应的直接原因:
1. 控件查找时机错误
在onCreateView方法中,你先调用了container.findViewById(R.id.button),但此时还未加载placeholder2.xml布局,container里根本不存在这个按钮控件,导致button变量为null,点击事件自然无法绑定,这就是初始点击按钮没反应的根源。
2. 潜在的ANR与内存泄漏风险
你在doWebViewPrint中新建了独立的WebView,但未正确管理其生命周期;若页面加载耗时较长,还可能阻塞主线程引发ANR。另外,将临时WebView赋值给成员变量却未在Fragment销毁时清理,容易造成内存泄漏。
修正后的完整实现
第一步:修正CalendarFragment代码
public class CalendarFragment extends Fragment { private static final String TAG = "CalendarFragment"; private WebView mLayoutWebView; // 持有布局内的WebView,而非打印临时WebView @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // 先加载布局,获取根View View rootView = inflater.inflate(R.layout.placeholder2, container, false); // 从根View中查找按钮,而非container Button printBtn = rootView.findViewById(R.id.button); printBtn.setOnClickListener(v -> triggerWebViewPrint()); // 初始化布局内的WebView并加载目标HTML mLayoutWebView = rootView.findViewById(R.id.wv); WebSettings webSettings = mLayoutWebView.getSettings(); webSettings.setJavaScriptEnabled(true); // 若HTML依赖JS则开启 webSettings.setLoadWithOverviewMode(true); webSettings.setUseWideViewPort(true); mLayoutWebView.loadUrl("file:///android_asset/calendar.html"); return rootView; } private void triggerWebViewPrint() { if (mLayoutWebView == null) return; // 监听页面加载状态,确保加载完成后再打印 mLayoutWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); Log.i(TAG, "页面加载完成,启动打印流程"); createPrintJob(view); } }); // 若页面已加载完成,直接触发打印 if (mLayoutWebView.getProgress() == 100) { createPrintJob(mLayoutWebView); } } private void createPrintJob(WebView webView) { PrintManager printManager = (PrintManager) requireActivity() .getSystemService(Context.PRINT_SERVICE); String jobName = getString(R.string.app_name) + " 日历文档"; // 自定义打印属性(可选,比如纸张尺寸、分辨率) PrintAttributes printAttrs = new PrintAttributes.Builder() .setMediaSize(PrintAttributes.MediaSize.ISO_A4) .setResolution(new PrintAttributes.Resolution("custom", Context.PRINT_SERVICE, 300, 300)) .setColorMode(PrintAttributes.COLOR_MODE_COLOR) .build(); PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(jobName); printManager.print(jobName, printAdapter, printAttrs); } @Override public void onDestroyView() { super.onDestroyView(); // 清理WebView,避免内存泄漏 if (mLayoutWebView != null) { mLayoutWebView.stopLoading(); mLayoutWebView.setWebViewClient(null); mLayoutWebView.destroy(); mLayoutWebView = null; } } }
第二步:布局无需改动(可按需调整)
你的placeholder2.xml布局结构没问题,若需要适配更多设备,可将RelativeLayout替换为ConstraintLayout优化布局适配。
额外问题说明
- 关于
Cannot find SearchIndexableResources for PrintSettingsFragment日志:这是系统打印服务的内部日志,与你的应用代码无关,无需处理。 - 关于ANR问题:修正后的代码优化了WebView生命周期管理,避免了主线程阻塞;若仍出现ANR,建议检查你的HTML文档是否包含耗时的JS操作,或尝试拆分复杂页面逻辑。
内容的提问来源于stack exchange,提问作者Max Clifford
相关产品推荐
相关产品推荐

