Android 本地HTML屏幕适配的一种方案

Posted 周文凯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 本地HTML屏幕适配的一种方案相关的知识,希望对你有一定的参考价值。

转载请标明出处:
http://blog.csdn.net/xuehuayous/article/details/52757204
本文出自:【Kevin.zhou的博客】

前言:在android开发中WebView加载网页,网页的适配应该是前端来处理的,毕竟客户端的对网页的控制是有限的。但是如果有一个本地的网页而且该网页的body是固定宽度的,让我们去适配所有设备还是比较头疼的,当然这种应用场景是很罕见的,尽管如此我们还是讨论下该问题。

通常的网页适配

// 设置加载进来的页面自适应手机屏幕
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setLoadWithOverviewMode(true);

一般情况下客户端只需要设置如上两行就可以了,当然这两行可以解决绝大部分网页的适配问题。第一行就是设置WebView支持viewpoart,第二行是设置网页超过屏幕宽度时重新布局为屏幕宽度。

如果body设置了确切值

尽管这种在前段开发中是要极力避免的,但有时候为了方便开发还是采用了这种方式。

这里可以采用获取body的值然后根据WebView控件的宽度与body的宽度计算一个比例,然后设置给网页设置一个缩放比例。

JS获取body宽度

  • 定义JS接口
class htmlWidthInterface 
    @javascriptInterface
    public void getContentWidth(String value) 
        if (value != null) 
            int bodyWidth = Integer.parseInt(value);
        
    
 
  • 设置网页加载后调用JS接口返回body宽度
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new HTMLWidthInterface(), "HTMLWidth");

mWebView.setWebViewClient(new WebViewClient() 
    @Override
    public void onPageFinished(WebView view, String url) 
        mWebView.loadUrl("javascript:window.HTMLWidth.getContentWidth(document.body.offsetWidth);");

    
);

计算缩放比例

private void htmlAdjustWithPageWidth(float bodyWidth, String html, WebView webView) 
    // 计算要缩放的比例
    DisplayMetrics metric = new DisplayMetrics();
    ((Activity)mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
    float density = metric.density;  // 屏幕密度
    float scale = webView.getMeasuredWidth() / density / bodyWidth;
    String insertText = "<meta name=\\"viewport\\" content=\\"width="+ bodyWidth +"px initial-scale="+ scale
            + ", minimum-scale=0.1, maximum-scale=10.0, user-scalable=no\\"/>";
    insertBehindText(new File(html), "<head>", insertText);

在HTML插入viewpoart信息

/**
 * 在指定文本之后插入一段文本
 *
 * @param file
 * @param targetStr
 * @param insertStr
 * @return void:
 * @version 1.0
 * @date 2015-9-2
 * @Author zhou.wenkai
 */
public void insertBehindText(File file, String targetStr, String insertStr) 
    BufferedReader  bufr = null;
    BufferedWriter  bufw = null;
    try 
        InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
        bufr = new BufferedReader(isr);
        StringBuffer buf = new StringBuffer();
        String line = null;

        while ((line = bufr.readLine()) != null) 
            // 保存原文本
            buf = buf.append(line);
            // 保存要插入文本
            if(line.contains(targetStr)) 
                buf.append(insertStr);
            
            // 添加换行符号
            buf = buf.append(System.getProperty("line.separator"));
        
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
        bufw = new BufferedWriter(osw);
        bufw.write(buf.toString());
        bufw.close();

     catch (FileNotFoundException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
     finally 
        try 
            if(bufr != null) 
                bufr.close();
            
            if(bufw != null) 
                bufw.close();
            
         catch (IOException e) 
            e.printStackTrace();
        
    

源码

public class MainActivity extends AppCompatActivity 

    private final static String TAG = "WebViewContentWidth";
    private WebView mWebView;
    String path = Environment.getExternalStorageDirectory().getPath() + "/temp/HYLNK01/第一节_自我测试1.html";
//        path = Environment.getExternalStorageDirectory().getPath() + "/temp/HYLNK02/首页.html";
//        path = Environment.getExternalStorageDirectory().getPath() + "/temp/HYLNK03/home.html";;
    Context mContext;

    @SuppressLint("JavascriptInterface")
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;

        mWebView = (WebView) this.findViewById(R.id.main_act_wv);

        // 设置不可缩放
        mWebView.getSettings().setBuiltInZoomControls(false);
        mWebView.getSettings().setSupportZoom(false);
        mWebView.getSettings().setDisplayZoomControls(false);

        // 设置支持屏幕适配
        mWebView.getSettings().setUseWideViewPort(true);
        mWebView.getSettings().setLoadWithOverviewMode(true);

        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.addJavascriptInterface(new HTMLWidthInterface(), "HTMLWidth");

        mWebView.setWebViewClient(new WebViewClient() 
            @Override
            public void onPageFinished(WebView view, String url) 
                mWebView.loadUrl("javascript:window.HTMLWidth.getContentWidth(document.body.offsetWidth);");

            
        );

        mWebView.loadUrl("file://" + path);
    

    class HTMLWidthInterface 
        @JavascriptInterface
        public void getContentWidth(String value) 
            if (value != null) 
                int bodyWidth = Integer.parseInt(value);
                boolean hasChanged = isContainsText(new File(path), "<meta name=\\"viewport\\"");
                if(!hasChanged) 
                    htmlAdjustWithPageWidth(bodyWidth, path, mWebView);
                    mWebView.loadUrl("file://" + path);
                
            
        
    

    private void htmlAdjustWithPageWidth(float bodyWidth, String html, WebView webView) 
        // 计算要缩放的比例
        DisplayMetrics metric = new DisplayMetrics();
        ((Activity)mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
        float density = metric.density;  // 屏幕密度
        float scale = webView.getMeasuredWidth() / density / bodyWidth;
        String insertText = "<meta name=\\"viewport\\" content=\\"width="+ bodyWidth +"px initial-scale="+ scale
                + ", minimum-scale=0.1, maximum-scale=10.0, user-scalable=no\\"/>";
        insertBehindText(new File(html), "<head>", insertText);
    

    /**
     * 在指定文本之后插入一段文本
     *
     * @param file
     * @param targetStr
     * @param insertStr
     * @return void:
     * @version 1.0
     * @date 2015-9-2
     * @Author zhou.wenkai
     */
    public void insertBehindText(File file, String targetStr, String insertStr) 
        BufferedReader  bufr = null;
        BufferedWriter  bufw = null;
        try 
            InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
            bufr = new BufferedReader(isr);
            StringBuffer buf = new StringBuffer();
            String line = null;

            while ((line = bufr.readLine()) != null) 
                // 保存原文本
                buf = buf.append(line);
                // 保存要插入文本
                if(line.contains(targetStr)) 
                    buf.append(insertStr);
                
                // 添加换行符号
                buf = buf.append(System.getProperty("line.separator"));
            
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
            bufw = new BufferedWriter(osw);
            bufw.write(buf.toString());
            bufw.close();

         catch (FileNotFoundException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
         finally 
            try 
                if(bufr != null) 
                    bufr.close();
                
                if(bufw != null) 
                    bufw.close();
                
             catch (IOException e) 
                e.printStackTrace();
            
        
    

    /**
     * 检查是否包含制定文本
     *
     * @param file
     * @param containsStr
     * @return
     * @return boolean:
     * @version 1.0
     * @date 2015-10-28
     * @Author zhou.wenkai
     */
    public boolean isContainsText(File file, String containsStr) 
        BufferedReader bufr = null;
        try 
            InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
            bufr = new BufferedReader(isr);
            String line;

            while ((line = bufr.readLine()) != null) 
                if(line != null && line.contains(containsStr)) 
                    return true;
                
            

         catch (FileNotFoundException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
         finally 
            try 
                if(bufr != null) 
                    bufr.close();
                
             catch (IOException e) 
                e.printStackTrace();
            
        
        return false;
    

以上是关于Android 本地HTML屏幕适配的一种方案的主要内容,如果未能解决你的问题,请参考以下文章

android屏幕适配方案

Android 屏幕适配方案

Android屏幕适配方案

Android开发:最全面最易懂的Android屏幕适配解决方案

iOS屏幕适配方案-Auto Layout

Android屏幕适配全攻略(最权威的官方适配指导)