WebView 기본 사용법(웹페이지 보기)


이 섹션 소개

이 섹션에서는 Android에서 웹 페이지 표시를 위한 컨트롤인 WebView(웹 페이지 보기)을 제공합니다.

이제 안드로이드 앱 레이어 개발에는 클라이언트 개발과 HTML5 모바일 개발이라는 두 가지 방향이 있습니다!

소위 HTML5의 끝은 HTML5 + CSS + JS로 구축하는 것입니다. 웹 버전의 애플리케이션과 중간 매체는 WebView이며 웹과 웹 페이지는 JS를 통해 상호 작용할 수 있습니다. 예를 들어 다음과 같습니다. 웹페이지에서는 휴대폰 연락처를 읽고, 휴대폰 관련 API를 호출하는 등!

일반 클라이언트 개발과 비교할 때 HTML5 모바일 터미널은 다음과 같은 장점이 있습니다. 레이아웃에 백분율을 사용할 수 있으며 HTML5 측에 큰 변경 사항이 있는 경우 클라이언트처럼 APP를 다시 생성할 필요가 없습니다. 설치를 덮어쓰려면 웹페이지만 수정하면 됩니다! 그리고 클라이언트는... 물론 HTML5에도 성능 문제라는 단점이 있습니다. 데이터 축적, 전력 소모 문제, 화면 깜박임 등...

또한 이러한 크로스 플랫폼의 경우 다른 타사를 활용하여 빠르게 개발할 수 있습니다. PhoneGap과 같은 프레임워크도 있습니다. 인터넷에는 원클릭 APP와 유사한 웹사이트도 많이 있습니다. 사용자는 끌어서 놓아 사진을 설정할 수 있습니다. 이와 같은 간단한 작업을 통해 애플리케이션을 생성할 수 있으며 대부분 HTML5를 사용하여 수행됩니다! 템플릿도 있으니 적용해 보세요~ 좋아요, 더 이상 고민하지 말고 이 섹션을 시작하겠습니다!

1. 웹뷰란?

답변: Android에는 웹킷 커널이 내장된 고성능 브라우저가 있으며 이를 기반으로 WebView가 캡슐화됩니다. Control, WebView는 웹 보기를 문자 그대로 번역한 것으로 간단히 인터페이스에 중첩될 수 있는 브라우저 컨트롤로 간주할 수 있습니다!

2. 관련 방법

먼저 공식 문서로 이동하세요: WebView속성을 하나씩 이야기하고, 어떤 속성이 사용되는지 쓰고, 다른 정보는 문서에서 직접 확인할 생각은 없습니다! 직접적인 WebView 외에도 사용자 고유의 동작을 추가할 수 있으며 다음 클래스를 사용자 정의할 수도 있습니다.


WebChromeClient: WebView가 Javascript 대화 상자, 웹 사이트 아이콘, 웹 사이트 제목, 로딩 진행률 등을 처리하도록 지원합니다! 예:

MethodFunction
onJsAlert(WebView 뷰, 문자열 URL, 문자열 메시지, JsResult 결과)Js에서 경고 대화 상자 처리
sConfirm(WebView 보기, 문자열 url,문자열 메시지,JsResult 결과)Js에서 확인 대화 상자 처리
onJsPrompt(WebView 보기, 문자열 url, 문자열 메시지, 문자열 defaultValue,JsPromptResult 결과)Js에서 프롬프트 대화 상자 처리
onProgressChanged(WebView 뷰, int newProgress)로딩 진행률 표시줄이 변경될 때 호출
onReceivedIcon(WebView 뷰, 비트맵 아이콘)웹페이지 아이콘 가져오기
onReceivedTitle (WebView 보기, 문자열 제목)웹 페이지 제목 가져오기

WebViewClient: WebView가 다양한 알림 및 요청 이벤트를 처리하도록 지원하세요! 예를 들어 다음 방법은 다음과 같습니다.

MethodFunction
onPageStared(WebView view, String url)메인 프로그램에 웹 페이지 로딩이 시작됨을 알립니다.
페이지완료 (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 뷰, KeyEvent 이벤트)webView가 키 누름 시간을 처리할지 여부를 제어합니다. true를 반환하면 WebView는 이를 처리하지 않습니다
shouldOverrideUrlLoading(WebView 보기, 문자열 url)새로 로드된 Url의 처리를 제어하고 true를 반환합니다. 이는 기본 프로그램이 WebView를 처리하지 않는다는 것을 나타냅니다. false를 반환하면 WebView가 이를 처리한다는 의미입니다
onReceivedError(WebView 보기 , int errorCode, 문자열 설명, 문자열 failedUrl)호출 시 복구할 수 없는 오류 메시지가 발생했습니다.

WebSettings: WebView 관련 구성 설정(예: setJavaScriptEnabled()) JS 스크립트 실행 허용 여부 설정 일부 메소드는 다음과 같습니다.

methodfunction
getSettings()은 WebView
의 속성 설정을 제어하는 ​​데 사용되는 WebSettings 객체를 반환합니다. loadUrl(문자열 url) 지정된 Url을 로드
loadData(문자열 데이터, 문자열 mimeType, 문자열 인코딩)지정된 데이터를 WebView에 로드합니다. "data:"를 태그 헤더로 사용합니다. 이 방법은 네트워크 데이터를 로드할 수 없습니다. . mimeType textml, image/jpeg와 같은 데이터 유형의 경우 인코딩은 문자 인코딩 방법입니다
loadDataWithBaseURL(String baseUrl, String data, String mimeType, String 인코딩, String HistoryUrl) 위의 loadData보다
setWebViewClient(WebViewClient 클라이언트)WebView에 대한 WebViewClient 개체를 지정하면 WebViewClient는 WebView가 다양한 알림, 요청 및 기타 이벤트를 처리하는 데 도움을 줄 수 있습니다.
setWebChromeClient(WebChromeClient 클라이언트)WebView용 WebChromeClient 개체를 지정합니다. WebChromeClient는 특별히 WebView가 js 대화 상자, 웹 사이트 제목, 웹 사이트 아이콘, 진행률 표시줄 로드 등을 처리하는 데 사용됩니다.

여기서 세 가지 로드 방법의 차이점을 구별하는 것이 중요합니다.

loadUrl(): 웹 페이지 콘텐츠를 직접 표시합니다(네트워크 이미지만 표시). 일반적으로 잘못된 문자가 표시되지 않습니다. loadData(data, "text/html", "UTF-8"): URI 형식의 데이터를 로드하는 데 사용됩니다. 콘텐츠는 네트워크를 통해 로드할 수 없습니다. 이미지를 로드할 수 없으며 잘못된 문자가 자주 발견됩니다. 문자열 유형 데이터는 주로 유니코드로 인코딩됩니다. WebView는 일반적으로 리소스를 저장하기 위해 UTF-8 인코딩을 사용합니다. 위에서 작성했지만 여전히 webView에 대해 설정해야 합니다. webview.getSettings().setDefaultTextEncodingName("UTF -8");loadDataWithBaseURL(baseUrl, string, "text/html", "utf-8", null): loadData 클래스 중 하나 향상된 클래스, 이미지를 로드할 수 있고 baseUrl은 저장된 이미지 경로이며 여기에서 utf-8만 설정하면 잘못된 코드를 해결할 수 있습니다. 문제!

이것은 일부 속성의 목록일 뿐이며, 다른 경우에는 공식 문서를 직접 확인해야 합니다.

WebChromeClient Documentation

WebViewClient Documentation

WebSettings Documentation


3. 공통 요구 사항

요구 사항 1: URL에 따라 웹 페이지 로드

1) Activity에서 직접 WebView 로드

렌더링 실행:

1.gif

구현 코드:

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) 레이아웃 코드에 WebView를 설정하세요

뉴스 앱이나 포털 정보 앱을 많이 보셨을 텐데요. 구조는 다음과 같습니다.

2.png

왼쪽 상단에 현재 활동을 닫는 버튼 중앙에는 뉴스 제목이 있고 오른쪽에는 새로 고침 버튼이 있습니다. 화면 너비 이상으로 슬라이드하면 오른쪽 하단에 이러한 플로팅 버튼이 있을 수 있습니다. 사용자가 클릭하면 웹페이지 상단으로 다시 스크롤됩니다! 간단하게 구현해보자!

렌더링 실행:

3.gif

구현 코드:

MainActivity.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();
            }

        }
    }
}

질문 및 답변:

나는 신중한 친구들이 우리가 우리가 했던 일로 돌아가서 처음에 로드됨 페이지에 들어간 후 Return 키를 여러 번 눌러도 여전히 종료되지 않습니다. 현재 앱의 경우 현재 활동을 닫으려면 뒤로 버튼을 수동으로 클릭하고 종료 메서드를 호출해야 합니까? 왜 이런가요? 분명 바이두의 첫 페이지겠죠?

답변: 사실 그 이유는 URL의 리디렉션 문제입니다. 실제로 Baidu를 방문했을 때:

www.baidu.com을 로드했지만 Baidu는 리디렉션을 수행하여 Baidu의 모바일 버전으로 점프했습니다. 웹사이트: 즉, 실제 프로세스는 다음과 같습니다. www.baidu.com -> Baidu 모바일 버전 ->

위의 shouldOverrideUrlLoading() 메소드는 다음과 같이 작성되었습니다.

view.loadUrl(url); return true 사용자가 뒤로 버튼을 한 번 클릭하면 webview가 goback 메소드를 호출한다는 것을 알고 있습니다. ) 한 번, 상위 3개를 넣습니다. A, B, C 세 개의 사이트가 있다고 가정해 보겠습니다. C에서 다시 클릭하면 C - > B가 됩니다. 그런 다음 B - > A를 클릭하면 문제가 발생합니다. B가 A로 왔는데도 리다이렉션 때문에 다시 B로 점프하는 것 등등.. 이래서 뒤로 버튼을 눌렀을 때 WebView가 실행되지 않는 이유, 해결 방법: 손 속도, WebView에 웹 페이지가 로드되지 않음 뒤로가기 버튼을 계속 더블클릭하시면 손의 속도가 충분히 빨라지실 겁니다. 하하! 농담이에요. 이 문제를 해결하려면 shouldOverrideUrlLoading의 항목을 삭제하고 return false를 작성하세요. 리디렉션이라고 생각되지 않으면 URL을 직접 수정해 보세요~


요구 사항 2: WebView 스크롤 이벤트 모니터링

스크롤 이벤트 모니터링에는 일반적으로 setOnScrollChangedListener 설정이 포함된다는 것을 우리 모두 알고 있습니다. WebView는 이러한 메서드를 제공하지 않지만 WebView를 다시 작성하고 해당 메서드 중 하나를 재정의할 수 있습니다. protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt){} 그런 다음 외부 세계에 대한 인터페이스를 제공합니다. 샘플 코드는 다음과 같습니다.

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();
            }

        }
    }
}

Runningerings:

4.gif

스크롤하려면 Hehe 버튼을 클릭하고 Hehe 버튼을 클릭하면 맨 위로 돌아갑니다! 그럼 히히 버튼이 숨겨집니다~


요구사항 3: 스크롤바 문제

사용할 수 있는 속성은 다음과 같습니다.

  • setHorizontalScrollBarEnabled(false); //가로가 표시되지 않습니다
  • setVerticalScrollBarEnabled(false); //세로가 표시되지 않음 Display
  • setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);//스크롤 막대가 WebView 내부에 표시됩니다
  • setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY)//스크롤 막대가 WebView 외부에 표시됩니다

요구 사항 4: 크기 조정 및 적응형 화면 설정

우리는 웹 페이지를 열 때 일반적으로 WebView가 잘 보이지 않을 때 두 손가락으로 웹 페이지를 확대하거나 축소하는 것을 좋아합니다. 이것이 스케일링을 지원하는지 수동으로 설정해야 합니다!

다음 코드를 추가하세요:

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

위 코드를 사용한 후 페이지는 다음과 같습니다:

5.png

줌을 하면 매우 일반적인 줌 컨트롤인 역겨운 문제가 발생합니다. 그런 다음 확대/축소 컨트롤을 숨기려면 다음 코드를 추가하세요!

settings.setDisplayZoomControls(false);

webView에 대해서만 초기 확대/축소 비율을 직접 설정할 수도 있습니다.

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

야, 위는 전체 웹페이지를 확대한 것이지만 때로는 글꼴 크기만 조정하면 됩니다.

settings.setTextZoom(int);

settings.setTextSize(TextSize.LARGER);

를 통해 직접 크기를 설정할 수도 있습니다.

Android에는 SMALLEST(50%), SMALLER(75%), NORMAL(100%), LARGER(150%), LARGEST(200%)의 5가지 선택적 글꼴 크기 값이 있습니다.


요구 사항 5. WebView의 쿠키 데이터 가져오기

우리 모두는 쿠키가 실제로 사용자의 고유 식별자를 나타내는 문자열일 뿐이라는 것을 알고 있습니다. 일반적으로 시나리오는 다음과 같습니다. 사용자가 계정 비밀번호를 입력하고 클릭하여 로그인한 후, 사용자는 이 쿠키를 사용하여 서버에서 제공하는 관련 서비스에 접속해야 합니다! onPageFinsihed 메소드에 쿠키 획득을 작성할 수 있습니다. 다음과 같이 간단하게 작성할 수 있습니다.

@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);
}

요구 사항 6. WebView의 쿠키 데이터 설정

야, 위에서 쿠키를 얻었거나 다른 방법을 통해 쿠키를 얻었습니다. WebView에 대한 쿠키 설정은 어떻습니까? 쿠키를 설정해야 하는 곳에 다음 코드를 추가할 수 있습니다.

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

그런데 위 코드는 loadUrl() 이전에 작성해야 하며, 쿠키가 설정된 경우에는 다른 설정을 하지 않도록 하세요. 그렇지 않으면 유효하지 않을 수 있습니다. webView 관련 설정 끝 ~


4. 샘플 코드 다운로드:

WebViewDemo1: Download WebViewDemo1.zip

WebViewDemo2 : WebViewDemo2를 다운로드하세요. zip


이 섹션 요약:

자, 이 섹션에서는 WebView의 기본 사용법, 웹 페이지 로딩, 크기 조정, 글꼴 크기 조정, 적응형 화면, 쿠키 획득 및 설정 등 일상적인 개발에는 다양한 요구 사항이 있다고 생각합니다. 공간의 제약으로 인해 너무 많은 내용만 작성하겠습니다. 아이디어에 대한 환영 메시지가 있는 경우 다음 섹션에서는 HTML5 측에서 JavaScript를 사용하는 방법을 알아보겠습니다. WebView와 상호 작용하고 휴대폰의 관련 데이터를 얻으세요! 기대해주세요~감사합니다~