这是一个安卓的`WebView’教程和例子。WebView "是android SDK的一个视图,能够渲染网页。

什么是 "WebView"?

正如我们所说,`WebView’是一个能够显示网页的视图。

它由WebView类表示。这个类比你想象的要强大得多。但它使用起来非常简单明了,并为你提供了抽象的基础。

正是这个类作为基础,你可以创建你自己的网络浏览器或简单地在你的活动'中显示一些在线内容。WebView`利用WebKit渲染引擎来显示网页,并包括以下方法。

  1. 在历史中向前和向后导航
    2.放大和缩小。
    3.进行文本搜索等等。

WebView非常强大,因为它为你提供了一种用Javascript和HTML标记等语言编写应用程序的方法。有很多框架都利用了这种能力,从而使你可以用HTML5技术编写应用程序。你甚至可以把你的网站,比如说wordpress网站变成一个安卓应用。

中國八字2023黑水兔

中國八字2023黑水兔
中國八字2023黑水兔

WebView API的定义

WebView是一个具体的类,位于android.webkit包中。它派生自android.widget.AbsoluteLayout类,实现了几个接口,如下所示。

public class WebView extends AbsoluteLayout implements ViewTreeObserver.OnGlobalFocusChangeListener, ViewGroup.OnHierarchyChangeListener

下面是它的继承层次。

java.lang.Object
   ↳    android.view.View
       ↳    android.view.ViewGroup
           ↳    android.widget.AbsoluteLayout
               ↳    android.webkit.WebView

为什么是Webview?

WebView可能是android中最实用、最容易使用而又未被充分利用的类之一。这是因为它基本上允许你使用HTML、CSS和Javascript来创建一个安卓应用。如果它不能执行Javascript或渲染CSS,那么我可以理解它没有被广泛使用。然而,它能做到所有这些。

这就提供了强大的功能,因为HTML、CSS和Javascript都是易于使用的流行技术,几乎所有你曾经访问过的网络应用程序或网站的用户界面都采用这些技术。此外,有数百个框架/库为这些技术提供了强大的小工具和抽象。这些包括jQuery、Vue.js、Angular、React.js、Bootstrap、materializecss、UIKit等。

你可以很容易地创建一个简单的客户端网络应用,可以与服务器端技术如Node.js和PHP进行交互,然后放在你的assets文件夹中。然后使用WebView来加载它。然而,你必须确保Javascript被启用。我知道这不如用Java或Kotlin或C#编写的完整的Java应用程序强大,但是,对于初学者来说,你可以快速启动你的第一个应用程序,你可以在继续学习时向朋友展示。

使用`WebView

大多数时候,你会想在你的webview中渲染在线内容。所以为了让你的Activity能够访问互联网并在WebView中加载网页,你必须在Android Manifest文件中添加INTERNET权限。

<uses-permission android_name="android.permission.INTERNET" />

然后在你的布局中添加一个<WebView>,或者在onCreate()中把整个Activity窗口设置为WebView

 WebView webview = new WebView(this);
 setContentView(webview);

一旦你完成了这些,你就可以通过loadUrl()方法加载你的网页。

 // Simplest usage: note that an exception will NOT be thrown
 // if there is an error loading this page (see below).
 webview.loadUrl("https://camposha.info/");

loadurl()将从我们提供的URL加载我们的网站。这是最常用的方法。

你也可以从一个HTMLstring中加载。

 String summary = "<html><body>You scored <b>192</b> points.</body></html>";
 webview.loadData(summary, "text/html", null);
 // ... although note that there are restrictions on what this HTML can do.
 // See the JavaDocs for loadData() and loadDataWithBaseURL() for more info.

这基本上意味着你把你的HTML代码写在一个字符串'里面。然后通过loadData()`方法加载它。这适用于加载具有简单DOM(文档对象模型)结构的网站。

快速的`WebView’例子和操作方法

让我们来看看我们的webview类的快速方法。稍后我们将看到如何编写一个完整的应用程序。

1. 常用的WebView设置

这里有一些常用的`WebView’设置。让我们把它们封装在一个简单的静态方法中,然后我们可以很容易地重复使用。

    // Commonly used WebViewSetting
    public static void initWebSetting(WebView webView) {
        WebSettings setting = webView.getSettings();
        setting.setJavaScriptEnabled(true);
        setting.setAllowFileAccess(true);
        setting.setAllowFileAccessFromFileURLs(true);
        setting.setAllowUniversalAccessFromFileURLs(true);
        setting.setAppCacheEnabled(true);
        setting.setDatabaseEnabled(true);
        setting.setDomStorageEnabled(true);
        setting.setCacheMode(WebSettings.LOAD_DEFAULT);
        setting.setAppCachePath(webView.getContext().getCacheDir().getAbsolutePath());
        setting.setUseWideViewPort(true);
        setting.setLoadWithOverviewMode(true);
        setting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            setting.setAllowFileAccessFromFileURLs(true);
        }
    }

该方法接收一个WebView对象。我们首先通过WebView类的getSettings方法获得webview的设置。然后我们通过setJavaScriptEnabled()方法启用javascript。这些设置方法中的大多数都接收一个布尔值来启用或禁用各种设置。

2. 如何创建一个自定义的 "WebView"?

我们想创建一个可以在NestedScrollView中使用的自定义Webview。

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;

public class MyWebView extends WebView {

    public MyWebView(Context context) {
        super(context);
    }

    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        //Check pointer index to avoid -1 (error)
        if (MotionEventCompat.findPointerIndex(event, 0) == -1) {
            return super.onTouchEvent(event);
        }

        if (event.getPointerCount() >= 1) {
            requestDisallowInterceptTouchEvent(true);
        } else {
            requestDisallowInterceptTouchEvent(false);
        }

        return super.onTouchEvent(event);
    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
        super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        requestDisallowInterceptTouchEvent(true);
    }
}

1. Android WebView – 从URL、字符串和资产文件夹加载

Android WebView – 从URL、字符串和资产文件夹加载

WebView实际上是android中从一开始就存在的类之一。

它被添加到API级别1中,位于android.webkit包中。它被用来在 "活动 "中直接显示网络内容。这使得它非常强大,甚至可以用来建立一个可以工作的基本浏览器。它仍然是一个视图,所以我们可以简单地把它从托盘上拖到我们的布局上。它使用webkit渲染引擎渲染网页。在这个例子中,我们使用一个webview来渲染来自.NET的网页内容。

  • URL在线。
  • 本地`资产’文件夹。
  • java代码中的 "字符串"。

要从URL加载,你必须在androidmanifest.xml中获得android internet权限。你可以找到更多关于WebView的细节这里

屏幕截图
  • 以下是项目的截图。

这个例子所探讨的共同问题
  • 什么是WebView
  • 如何在webview中从url加载网站。
  • 如何在webview中从assetsfrolder加载html。
  • 如何在webview中加载htmlstring
  • 如何在android的 "activity "中使用webview。
使用的工具

这个例子是用以下工具写的。

  • Windows 8
  • AndroidStudio IDE
  • Genymotion仿真器
  • 语言:Java

在这个项目中没有使用第三方库。

让我们直接跳到源代码。

AndroidManifest.xml
  • Android Manifest文件。
  • 添加互联网权限,因为我们也要从URL中获取网页。

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="com.tutorials.hp.webviewer">

    <uses-permission android_name="android.permission.INTERNET"/>
    ...
</manifest>
Build.Gradle
  • 通常在Android项目中,有两个build.gradle文件。一个是应用级的build.gradle',另一个是项目级的build.gradle’。应用级属于app文件夹内,我们通常在这里添加我们的依赖项,并指定编译和目标SDK。
  • 同时添加AppCompat和设计支持库的依赖关系。
  • 我们的`MainActivity’将派生自AppCompatActivity,而我们也将使用设计支持库中的浮动动作按钮。

dependencies {
    implementation 'com.android.support:appcompat-v7:26.+'
    implementation 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
    implementation 'com.android.support:design:26.+'
    testImplementation 'junit:junit:4.12'
}
MainActivity.java
  • 启动器活动
  • ActivityMain.xml作为这个`活动’的内容视图膨胀。
  • 我们在这个`活动’中初始化视图和部件。
  • 我们在工具栏中切换菜单项,选择从url、assets或string中加载。

package com.tutorials.hp.webviewer;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {

    WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        webView= (WebView) findViewById(R.id.myWebview);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });
    }

    /*
    LOAD WEBSITE
     */

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.urlID) {
            //LOAD FROM URL
            webView.loadUrl("https://camposha.info");

            return true;
        }else if (id == R.id.assetsID) {

            //LOAD FROM ASSETS
            webView.loadUrl("file:///android_asset/Campo.html");

            return true;
        }else if (id == R.id.stringID) {

            //LOAD FROM STRING
            String html="<html><title></title><body>" +
                    "<h1><u>Programming Languages</u></h1>" +
                    "Below are some languages check them out: " +
                    "<ol>" +
                    "<li>Java</li><li>C#</li><li>C++</li><li>Python</li><li>PHP</li><li>Perl</li>" +
                    "</ol>" +
                    "</body></html>";
            webView.loadData(html,"text/html","UTF-8");

            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
ActivityMain.xml.
  • 模板布局。
  • 包含我们的ContentMain.xml
  • 也定义了appbarlayout, toolbar以及floatingaction buttton

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context="com.tutorials.hp.webviewer.MainActivity">

    <android.support.design.widget.AppBarLayout
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android_id="@+id/toolbar"
            android_layout_width="match_parent"
            android_layout_height="?attr/actionBarSize"
            android_background="?attr/colorPrimary"
            app_popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android_id="@+id/fab"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_gravity="bottom|end"
        android_layout_margin="@dimen/fab_margin"
        app_srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>
ContentMain.xml
  • 内容布局。
  • 定义了在 "主活动 "中显示的视图和小工具。
  • 在这种情况下,它是一个简单的webview。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    app_layout_behavior="@string/appbar_scrolling_view_behavior"
    tools_context="com.tutorials.hp.webviewer.MainActivity"
    tools_showIn="@layout/activity_main">

    <WebView
        android_id="@+id/myWebview"
        android_layout_width="match_parent"
        android_layout_height="match_parent"
        android_layout_centerHorizontal="true"
        />

</android.support.constraint.ConstraintLayout>
menu_main.xml
  • 我们将在我们的工具栏中切换菜单项。
  • 让我们在菜单目录下的menu_main.xml中定义它。

<menu

    tools_context="com.tutorials.hp.webviewer.MainActivity">
    <item
        android_id="@+id/action_settings"
        android_orderInCategory="100"
        android_title="@string/action_settings"
        app_showAsAction="never" />
    <item
        android_id="@+id/urlID"
        android_title="URL"
        app_showAsAction="never" />

    <item
        android_id="@+id/assetsID"
        android_title="Assets"
        app_showAsAction="never" />

    <item
        android_id="@+id/stringID"
        android_title="String"
        app_showAsAction="never" />
</menu>
下载
  • 下载下面的项目。
编号 位置 链接
1. GitHub 直接下载 2.
2. GitHub 浏览
结论。

我们看到了一个简单的android webview例子。如何通过url从网上加载网页,从assets文件夹和string数据。

如何将CSS注入到WebView

你可能想用CSS来操作一个你不拥有的页面。例如,假设一个网页被加载,然后你在CSS中应用你自己的样式。

这在android webview中是可以实现的。以下是具体步骤。

第1步:导入Base64

添加下面的导入。

import android.util.Base64

第2步:创建一个函数来注入css

这个函数将通过Javascript注入css。

private fun injectCSS() {
            try {
                val inputStream = assets.open("style.css")
                val buffer = ByteArray(inputStream.available())
                inputStream.read(buffer)
                inputStream.close()
                val encoded = Base64.encodeToString(buffer , Base64.NO_WRAP)
                webframe.loadUrl(
                    "javascript:(function() {" +
                            "var parent = document.getElementsByTagName('head').item(0);" +
                            "var style = document.createElement('style');" +
                            "style.type = 'text/css';" +
                            // Tell the browser to BASE64-decode the string into your script !!!
                            "style.innerHTML = window.atob('" + encoded + "');" +
                            "parent.appendChild(style)" +
                            "})()"
                )
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }

第三步: 覆盖 onPageFinished.

下一步是覆盖onpage finished事件,该事件在webview完成加载内容后被调用。

 override fun onPageFinished(view: WebView?, url: String?) {
                injectCSS()
}

这就是了。