Penggunaan asas WebView (paparan halaman web)


Pengenalan kepada bahagian ini

Apa yang dibawa oleh bahagian ini kepada anda ialah kawalan dalam Android untuk memaparkan halaman web: Paparan Web (paparan halaman web).

Apl Android Sekarang Terdapat dua arah untuk pembangunan lapisan: pembangunan pelanggan dan pembangunan mudah alih HTML5!

Apa yang dipanggil hujung HTML5 ialah: HTML5 + CSS + JS untuk dibina Versi web aplikasi, dan medium perantaraan ialah WebView, dan web serta halaman web boleh berinteraksi melalui JS, contohnya, Halaman web membaca kenalan telefon mudah alih, memanggil API berkaitan telefon mudah alih, dsb.!

Dan berbanding dengan pembangunan pelanggan biasa, terminal mudah alih HTML5 mempunyai kelebihan: Anda boleh menggunakan peratusan untuk reka letak dan jika terdapat sebarang perubahan besar pada bahagian HTML5, kami tidak perlu mencipta semula APP seperti yang dilakukan oleh pelanggan, dan kemudian Untuk menulis ganti pemasangan, kami hanya perlu mengubah suai halaman web! Dan pelanggan... sudah tentu, HTML5 juga mempunyai kekurangan, iaitu isu prestasi. Pengumpulan data, isu penggunaan kuasa, skrin berkelip, dsb...

Selain itu, untuk platform merentas jenis ini, kami boleh menggunakan pembangunan pesat pihak ketiga yang lain Rangka kerja, seperti PhoneGap, ya, terdapat juga banyak laman web seperti APP satu klik di Internet Pengguna boleh seret dan lepas untuk menetapkan gambar. Operasi mudah seperti ini boleh menjana aplikasi, kebanyakannya dilakukan menggunakan HTML5! Templat dah ada, pakai saja tau~ Okay, tanpa berlengah lagi, mari mulakan bahagian ini!

1. Apakah itu WebView?

Jawapan: Android ialah penyemak imbas berprestasi tinggi dengan kernel webkit terbina dalam dan WebView dirangkumkan atas dasar ini. Kawalan, WebView terjemahan literal paparan web, kita boleh menganggapnya sebagai kawalan pelayar yang boleh bersarang pada antara muka!

2. Kaedah yang berkaitan

Pergi ke dokumentasi rasmi dahulu: WebView tidak berhasrat untuk bercakap tentang atribut satu demi satu, dan tulis yang mana satu digunakan Untuk maklumat lain, sila rujuk dokumentasi sendiri! Sebagai tambahan kepada WebView langsung, kami juga boleh menambah tingkah laku anda sendiri dan menyesuaikan kelas berikut:


WebChromeClient: membantu WebView dalam memproses kotak dialog Javascript dan ikon tapak web , tajuk tapak web, kemajuan pemuatan, dsb.! Contohnya:

方法作用
onJsAlert(WebView view,String url,String message,JsResult result)处理Js中的Alert对话框
onJsConfirm(WebView view,String url,String message,JsResult result)处理Js中的Confirm对话框
onJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result)处理Js中的Prompt对话框
onProgressChanged(WebView view,int newProgress)当加载进度条发生改变时调用
onReceivedIcon(WebView view, Bitmap icon)获得网页的icon
onReceivedTitle(WebView view, String title)获得网页的标题

WebViewClient: Membantu WebView mengendalikan pelbagai pemberitahuan dan meminta acara! Contohnya, kaedah berikut:

< td align="left"><🎜>shouldOverrideUrlLoading<🎜>(WebView view,String url)
Kaedah Fungsi< /th>
方法作用
onPageStared(WebView view,String url)通知主程序网页开始加载
onPageFinished(WebView view,String url,Bitmap favicon)通知主程序,网页加载完毕
doUpdateVisitedHistory(WebView view,String url,boolean isReload)更新历史记录
onLoadResource(WebView view,String url)通知主程序WebView即将加载指定url的资源
onScaleChanged(WebView view,float oldScale,float newScale)ViewView的缩放发生改变时调用
shouldOverrideKeyEvent(WebView view,KeyEvent event)控制webView是否处理按键时间,如果返回true,则WebView不处理,返回false则处理
shouldOverrideUrlLoading(WebView view,String url)控制对新加载的Url的处理,返回true,说明主程序处理WebView不做处理,返回false意味着WebView会对其进行处理
onReceivedError(WebView view,int errorCode,String description,String failingUrl)遇到不可恢复的错误信息时调用
onPageStared<🎜>(Paparan Web, url Rentetan)
Beritahu program utama bahawa halaman web mula dimuatkan
<🎜>onPageFinished<🎜>(Paparan Web View, url String, Bitmap favicon)< /td>Beritahu program utama bahawa halaman web dimuatkan
<🎜>doUpdateVisitedHistory<🎜>(Paparan WebView ,String url,boolean isReload)Kemas kini sejarah
<🎜>onLoadResource<🎜>(WebView view ,String url) Beritahu program utama bahawa WebView akan memuatkan sumber url yang ditentukan
<🎜>onScaleChanged<🎜>(WebView view, float oldScale , float newScale)Dipanggil apabila skala ViewView berubah
<🎜>shouldOverrideKeyEvent<🎜>( WebView view, KeyEvent event)Kawal sama ada webView memproses masa menekan kekunci Jika benar dikembalikan, WebView tidak akan memprosesnya . Jika false dikembalikan, ia akan diproses.
Kawal pemprosesan Url yang baru dimuatkan, kembalikan benar, menunjukkan bahawa program utama memproses pemprosesan WebView No, mengembalikan palsu bermakna WebView akan memprosesnya
<🎜>onReceivedError<🎜>(WebView view,int errorCode,String description, String failingUrl)Dipanggil apabila menghadapi mesej ralat yang tidak boleh dipulihkan

Tetapan Web: Tetapan konfigurasi berkaitan WebView, seperti tetapan setJavaScriptEnabled() sama ada untuk membenarkan pelaksanaan skrip JS Beberapa kaedah adalah seperti berikut:

KaedahFungsi
方法作用
getSettings()返回一个WebSettings对象,用来控制WebView的属性设置
loadUrl(String url)加载指定的Url
loadData(String data,String mimeType,String encoding)加载指定的Data到WebView中.使用"data:"作为标记头,该方法不能加载网络数据.其中mimeType为数据类型如:textml,image/jpeg. encoding为字符的编码方式
loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)比上面的loadData更加强大
setWebViewClient(WebViewClient client)为WebView指定一个WebViewClient对象.WebViewClient可以辅助WebView处理各种通知,请求等事件。
setWebChromeClient(WebChromeClient client)为WebView指定一个WebChromeClient对象,WebChromeClient专门用来辅助WebView处理js的对话框,网站title,网站图标,加载进度条等
getSettings<🎜>()
Mengembalikan WebSettings objek, Digunakan untuk mengawal tetapan sifat WebView
<🎜>loadUrl<🎜>(String url)Memuatkan Url Ditentukan
<🎜>loadData<🎜>(Data rentetan,Jenis mime rentetan, Pengekodan rentetan)Muatkan Data yang ditentukan ke dalam WebView. Gunakan "data:" sebagai pengepala tanda. Kaedah ini tidak boleh memuatkan data rangkaian. mimeType ialah jenis data seperti: textml, image/jpeg. pengekodan ialah kaedah pengekodan aksara
<🎜>loadDataWithBaseURL<🎜>(String baseUrl, String data, String mimeType, String encoding, String historyUrl) Daripada di atas LoadData lebih berkuasa
<🎜>setWebViewClient<🎜>(WebViewClient client) Tentukan objek WebView WebViewClient boleh membantu WebView dalam mengendalikan pelbagai pemberitahuan, permintaan dan acara lain.
<🎜>setWebChromeClient<🎜>(WebChromeClient client)Tentukan objek WebChromeClient untuk WebView, WebChromeClient Digunakan secara khusus untuk membantu WebView dalam memproses kotak dialog js, tajuk tapak web, ikon tapak web, memuatkan bar kemajuan, dsb.

Adalah penting untuk membezakan perbezaan antara tiga kaedah pemuatan di sini:

loadUrl(): Paparkan kandungan halaman web secara langsung (paparkan imej rangkaian secara berasingan), secara amnya tiada watak bercelaru akan muncul. loadData(data, "text/html", "UTF-8"): digunakan untuk memuatkan data dalam format URI Kandungan tidak boleh dimuatkan melalui rangkaian. Imej tidak boleh dimuatkan, dan aksara bercelaru sering ditemui. Kami tahu bahawa data jenis rentetan terutamanya dikodkan Unicode. WebView biasanya menggunakan pengekodan UTF-8 untuk menyimpan sumber Walaupun kami menulisnya di atas, kami masih perlu menetapkannya untuk webView: webview.getSettings().setDefaultTextEncodingName("UTF -8");loadDataWithBaseURL(baseUrl, string, "text/html", "utf-8", null): salah satu daripada kelas loadData Kelas yang dipertingkatkan, anda boleh memuatkan imej, baseUrl ialah laluan imej yang disimpan untuk anda dan anda hanya perlu menetapkan utf-8 di sini untuk menyelesaikan kod yang bercelaru. Masalah!

Berikut adalah beberapa atribut yang disenaraikan untuk yang lain, anda perlu menyemak sendiri dokumentasi rasmi:

Dokumentasi WebChromeClient

Dokumen WebViewClient

Dokumen Tetapan Web


3. Penjelasan beberapa keperluan biasa

Keperluan 1: Muatkan halaman web mengikut URL

1) Muatkan WebView terus pada Aktiviti

Jalankan pemaparan :

1.gif

Kod pelaksanaan:

public class MainActivity extends AppCompatActivity {

    private WebView webView;
    private long exitTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = new WebView(this);
        webView.setWebViewClient(new WebViewClient() {
            //设置在webView点击打开的新网页在当前界面显示,而不跳转到新的浏览器中
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
        webView.getSettings().setJavaScriptEnabled(true);  //设置WebView属性,运行执行js脚本
        webView.loadUrl("http://www.baidu.com/");          //调用loadView方法为WebView加入链接
        setContentView(webView);                           //调用Activity提供的setContentView将webView显示出来
    }


    //我们需要重写回退按钮的时间,当用户点击回退按钮:
    //1.webView.canGoBack()判断网页是否能后退,可以则goback()
    //2.如果不可以连续点击两次退出App,否则弹出提示Toast
    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序",
                        Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                super.onBackPressed();
            }

        }
    }
}

2) Tetapkan WebView dalam kod susun atur

Saya percaya anda telah melihat banyak aplikasi berita atau Apl Kelas maklumat portal, strukturnya mungkin seperti ini:

2.png

Terdapat butang di sudut kiri atas untuk menutup Aktiviti semasa di tengah ialah tajuk berita, dan di sebelah kanan ialah butang muat semula. Mungkin terdapat butang terapung di sudut kanan bawah Apabila kita meluncur melebihi lebar skrin, ia akan dipaparkan. Apabila pengguna mengklik, ia akan menatal kembali ke bahagian atas halaman web! Mari kita laksanakan dengan mudah!

Menjalankan pemaparan:

3.gif

Kod pelaksanaan:

Aktiviti Utama . java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {


    private Button btn_back;
    private TextView txt_title;
    private Button btn_top;
    private Button btn_refresh;
    private WebView wView;
    private long exitTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }


    private void bindViews() {
        btn_back = (Button) findViewById(R.id.btn_back);
        txt_title = (TextView) findViewById(R.id.txt_title);
        btn_top = (Button) findViewById(R.id.btn_top);
        btn_refresh = (Button) findViewById(R.id.btn_refresh);
        wView = (WebView) findViewById(R.id.wView);

        btn_back.setOnClickListener(this);
        btn_refresh.setOnClickListener(this);
        btn_top.setOnClickListener(this);

        wView.loadUrl("http://www.baidu.com");
        wView.setWebChromeClient(new WebChromeClient() {
            //这里设置获取到的网站title
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                txt_title.setText(title);
            }
        });


        wView.setWebViewClient(new WebViewClient() {
            //在webview里打开新链接
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_back:
                finish();          //关闭当前Activity
                break;
            case R.id.btn_refresh:
                wView.reload();    //刷新当前页面
                break;
            case R.id.btn_top:
                wView.setScrollY(0);   //滚动到顶部
                break;
        }
    }
    
    @Override
    public void onBackPressed() {
        if (wView.canGoBack()) {
            wView.goBack();
        } else {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序",
                        Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                finish();
            }

        }
    }
}

Soal Jawab

Saya percaya rakan-rakan yang berhati-hati akan melihat bahawa selepas kita kembali ke halaman yang dimuatkan pada mulanya, tekan kekunci kembali, tekan Cuba beberapa kali tetapi masih tidak keluar Untuk APP semasa, adakah kita perlu mengklik butang kembali secara manual dan memanggil kaedah penamat untuk menutup Aktiviti semasa? kenapa ni? Ia jelas merupakan halaman pertama di Baidu?

Jawapan: Sebenarnya, sebab mengapa ini berlaku ialah: masalah pengalihan URL Sebenarnya, semasa kami melawat Baidu:

Walaupun kami memuatkan www.baidu.com, Baidu I. melakukan ubah hala dan melompat ke versi mudah alih halaman web Baidu: Iaitu, proses sebenar anda ialah: www.baidu.com ->

Kami melihat bahawa kaedah shouldOverrideUrlLoading() kami di atas ditulis seperti ini:

view.loadUrl(url);return true;Kami tahu bahawa pengguna mengklik belakang butang sekali , kemudian webview akan memanggil kaedah goback () sekali, kami meletakkan tiga di atas Katakan terdapat tiga tapak A, B dan C. Jika anda klik semula pada C, maka C - > B baik. Kemudian klik B - > Walaupun B datang ke A, ia melompat ke B semula kerana ubah hala, dan seterusnya... Inilah sebabnya Sebab mengapa WebView tidak dilancarkan apabila mengklik butang belakang Penyelesaian: kelajuan tangan, halaman web tidak dimuatkan dalam paparan web. Klik dua kali butang belakang secara berterusan, dan kelajuan tangan anda mesti cukup laju, haha! Bergurau, untuk menyelesaikan masalah ini, kita hanya perlu Padamkan bahan dalam shouldOverrideUrlLoading dan tulis return false; Jika anda tidak percaya ia adalah ubah hala, anda boleh cuba mengubah suai URL sendiri~


Keperluan 2: Pemantauan acara penatalan WebView

Kita semua tahu bahawa penatalan pemantauan acara biasanya melibatkan penetapan setOnScrollChangedListener , sayang sekali WebView tidak memberikan kami kaedah sedemikian, tetapi kami boleh menulis semula WebView dan mengatasi salah satu kaedahnya: void dilindungi onScrollChanged(final int l, final int t, final int oldl, final int oldt){} Kemudian sediakan antara muka kepada dunia luar. Kod sampel adalah seperti berikut:

MyWebViewDemo.java:

/**
 * Created by Jay on 2015/9/11 0011.
 */
public class MyWebView extends WebView {

    private OnScrollChangedCallback mOnScrollChangedCallback;

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

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

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

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mOnScrollChangedCallback != null) {
            mOnScrollChangedCallback.onScroll(l - oldl, t - oldt);
        }
    }

    public OnScrollChangedCallback getOnScrollChangedCallback() {
        return mOnScrollChangedCallback;
    }

    public void setOnScrollChangedCallback(
            final OnScrollChangedCallback onScrollChangedCallback) {
        mOnScrollChangedCallback = onScrollChangedCallback;
    }

    public static interface OnScrollChangedCallback {
        //这里的dx和dy代表的是x轴和y轴上的偏移量,你也可以自己把l, t, oldl, oldt四个参数暴露出来
        public void onScroll(int dx, int dy);
    }

}

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    private MyWebView wView;
    private Button btn_icon;
    private long exitTime = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_icon = (Button) findViewById(R.id.btn_icon);
        wView = (MyWebView) findViewById(R.id.wView);
        wView.loadUrl("http://www.hao123.com");
        wView.setWebViewClient(new WebViewClient() {
            //在webview里打开新链接
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }
        });

        //比如这里做一个简单的判断,当页面发生滚动,显示那个Button
        wView.setOnScrollChangedCallback(new MyWebView.OnScrollChangedCallback() {
            @Override
            public void onScroll(int dx, int dy) {
                if (dy > 0) {
                    btn_icon.setVisibility(View.VISIBLE);
                } else {
                    btn_icon.setVisibility(View.GONE);
                }
            }
        });

        btn_icon.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                wView.setScrollY(0);
                btn_icon.setVisibility(View.GONE);
            }
        });

    }

    @Override
    public void onBackPressed() {
        if (wView.canGoBack()) {
            wView.goBack();
        } else {
            if ((System.currentTimeMillis() - exitTime) > 2000) {
                Toast.makeText(getApplicationContext(), "再按一次退出程序",
                        Toast.LENGTH_SHORT).show();
                exitTime = System.currentTimeMillis();
            } else {
                finish();
            }

        }
    }
}

Menjalankan rendering:

4.gif

Apabila halaman web mula menatal, butang hehe akan muncul Kami klik butang hehe untuk kembali ke puncak! Kemudian butang hehe akan disembunyikan~


Keperluan 3: Masalah bar skrol

Atribut yang boleh anda gunakan adalah seperti berikut:

  • setHorizontalScrollBarEnabled(false );//Tidak dipaparkan secara mendatar
  • setVerticalScrollBarEnabled(false); //Tidak dipaparkan secara menegak
  • setScrollBarStyle(View.SCROLLBARS_OUTSIDE/_OVERLAY is); 🎜>
  • setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)//Bar skrol dipaparkan di luar WebView

Keperluan 4: Tetapkan penskalaan dan skrin penyesuaian

<🎜 Buka mengikut kebiasaan umum kami Untuk bahagian halaman web yang tidak dapat dilihat dengan jelas, kami suka menggunakan dua jari untuk mengezum masuk dan keluar dari halaman web, dan WebView Kita perlu menetapkan secara manual sama ada ini menyokong penskalaan!

Anda hanya perlu menambah kod berikut:

WebSettings settings = wView.getSettings();
settings.setUseWideViewPort(true);//设定支持viewport
settings.setLoadWithOverviewMode(true);   //自适应屏幕
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
settings.setSupportZoom(true);//设定支持缩放

Selepas menggunakan kod di atas, halaman akan kelihatan seperti ini:

Apabila kami mengezum, masalah yang menjijikkan berlaku, iaitu kawalan zum yang sangat biasa Kami pasti tidak mahukannya. Kemudian tambah kod berikut untuk menyembunyikan kawalan zum!

settings.setDisplayZoomControls(false);

Kami juga boleh menetapkan sendiri nisbah penskalaan awal, hanya untuk webView:

wView.setInitialScale(25);//为25%,最小缩放等级

Hei, perkara di atas adalah penskalaan keseluruhan halaman web, tetapi kadangkala kita hanya perlu menskalakan fon , kemudian OK Lakukan ini:

settings.setTextZoom(int);

Anda juga boleh menetapkan saiz terus melalui:

settings.setTextSize(TextSize.LARGER);

.

Android datang dengan lima nilai saiz fon pilihan: PALING KECIL (50%), LEBIH KECIL (75%), BIASA (100%), LEBIH BESAR (150%), PALING BESAR (200%).


Keperluan 5. Dapatkan data kuki WebView

Kita semua tahu bahawa kuki sebenarnya hanyalah rentetan yang mewakili pengecam unik pengguna Senario ini secara amnya: Selepas pengguna memasukkan kata laluan akaun dan mengklik untuk log masuk, pengguna perlu menggunakan kuki ini untuk mengakses perkhidmatan berkaitan yang disediakan oleh pelayan! Kita boleh menulis pemerolehan kuki ke dalam kaedah onPageFinsihed Ia boleh ditulis secara ringkas seperti ini:

@Override
public void onPageFinished(WebView view, String url) {             
    CookieManager cookieManager = CookieManager.getInstance();
    String CookieStr = cookieManager.getCookie(url);
    Log.e("HEHE", "Cookies = " + CookieStr);
    super.onPageFinished(view, url);
}

Keperluan 6. Tetapkan data Kuki WebView

Hei, kami mendapat Kuki. di atas Atau jika kami memperoleh kuki melalui cara lain, bagaimanakah kami menetapkan kuki untuk WebView? Kita boleh menambah kod berikut di mana Cookie perlu ditetapkan:

CookieSyncManager.createInstance(MainActivity.this);  
CookieManager cookieManager = CookieManager.getInstance();  
cookieManager.setAcceptCookie(true);  
cookieManager.setCookie(url, cookies);  //cookies是要设置的cookie字符串 
CookieSyncManager.getInstance().sync();

By the way, kod di atas perlu ditulis sebelum loadUrl(), dan jika Cookie ditetapkan, cuba jangan buat tetapan lain. Jika tidak, ia mungkin tidak sah. Adalah disyorkan untuk menulis kuki di penghujung tetapan berkaitan webView ~ sebelum loadUrl()


4 :

Muat turun WebViewDemo1.zip

WebViewDemo2:

Muat turun WebViewDemo2.zip

Ringkasan bahagian ini:

Baiklah, bahagian ini memperkenalkan anda kepada penggunaan asas WebView, memuatkan halaman web, penskalaan tetapan dan penskalaan fon. Skrin penyesuaian, serta pemerolehan dan penetapan kuki; Saya percaya terdapat pelbagai keperluan pelik dalam pembangunan harian, tetapi Disebabkan oleh keterbatasan ruang, saya hanya akan menulis begitu banyak Jika anda mempunyai mesej selamat datang untuk idea, dalam bahagian seterusnya kita akan belajar cara menggunakan JavaScript pada bahagian HTML5. Datang berinteraksi dengan WebView dan dapatkan data berkaitan telefon anda! Nantikan~Terima kasih~