Android WebView渲染拉伸变形问题及RecyclerView富文本展示需求
I’ve run into this exact frustrating issue before—those weird stretch and distortion glitches when WebViews load inside RecyclerView items are such a pain. Here are a few tried-and-tested fixes to smooth things out:
1. Fix WebView Measurement with a Custom Class
WebView can be stubborn about calculating its height correctly in RecyclerView. Create a custom WebView that forces proper measurement once content finishes loading:
public class MeasuredWebView extends WebView { public MeasuredWebView(Context context) { super(context); setup(); } public MeasuredWebView(Context context, AttributeSet attrs) { super(context, attrs); setup(); } private void setup() { setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // Trigger re-measure to fit content exactly view.post(() -> { int contentHeight = view.getContentHeight() * view.getScale(); if (contentHeight != getHeight()) { LayoutParams params = getLayoutParams(); params.height = contentHeight; setLayoutParams(params); } }); } }); } }
Replace the standard WebView in your RecyclerView item layout with this custom class. This ensures the WebView adjusts its height perfectly to fit loaded content, eliminating initial stretching.
2. Delay Content Loading Until View is Ready
Often, the WebView starts loading content before its layout is fully initialized, leading to glitches. In your onBindViewHolder, use post() to delay loading until the view is attached and laid out:
@Override public void onBindViewHolder(MyViewHolder holder, int position) { String content = getItem(position); // Wait for the view to be ready before loading content holder.webView.post(() -> { WebSettings webSettings = holder.webView.getSettings(); webSettings.setDefaultFontSize(14); holder.webView.loadDataWithBaseURL(null, content, "text/html", "utf-8", null); }); }
3. Reset WebView State When Recycling
RecyclerView reuses views, so leftover state from previous items can cause visual artifacts. Reset the WebView before loading new content in onBindViewHolder:
@Override public void onBindViewHolder(MyViewHolder holder, int position) { // Clear previous content first holder.webView.stopLoading(); holder.webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); // Load new content String content = getItem(position); holder.webView.post(() -> { WebSettings webSettings = holder.webView.getSettings(); webSettings.setDefaultFontSize(14); holder.webView.loadDataWithBaseURL(null, content, "text/html", "utf-8", null); }); }
4. Adjust Hardware Acceleration Settings
Hardware acceleration can sometimes trigger rendering glitches in WebViews. Try disabling it for the WebView in your layout XML:
<com.yourpackage.MeasuredWebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:hardwareAccelerated="false" />
Or disable it programmatically if needed:
holder.webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Combining the custom measured WebView with delayed loading usually fixes most of these visual issues. Give these steps a shot!
内容的提问来源于stack exchange,提问作者user60108

