티스토리 뷰

1. 안드로이드 간단 인터넷 브라우저 만들어보기

이번 프로젝트는 일반적인 인터넷 브라우징이 가능한 simple web browser 만들기입니다. 안드로이드에서 제공하는 웹뷰를 사용하여 인터넷 서핑을 할 수 있고 위에서 아래로 쓸어서 새로고침 하기 등을 다뤄보겠습니다.

주요 기능

  • 웹 브라우징
  • 웹 페이지 로딩 프로그래스 (진행상황 표시)
  • 위에서 아래로 스와이프하여 새로고침
  • 홈 기능
  • 뒤/앞 네비게이션 기능

사용 기술

  • SwipeRefreshLayout
  • ConstraintLayout
  • EditText
  • WebView
  • ContentLoadingProgressBar

1.1. 기본 레이아웃 구성하기

기본 레이아웃의 경우 상단 툴바영역과 아래 웹뷰 영역으로 크게 나눠볼 수 있습니다. 상단 툴바는 제약 레이아웃으로 홈버튼 주소창 앞뒤로가기 버튼으로 구성되어있습니다.

주소 창의 경우에는 둥근 형태의 모습을 갖춰보이도록 속성을 가지는 drawable 자원을 추가해서 배경으로 설정 해줬습니다.

웹 뷰의 경우에는 SwipeRefreshLayout 내부에 포함되도록 구성하여 위에서 아래로 쓸어내렸을 때 새로고침 기능을 수행할 수 있게 해줍니다.

페이지가 로드되고 있을 때는 ContentLoadingProgressBar를 사용해서 로딩 프로그레스를 표시하도록 설정하도록 하여 유저에게 앱이 동작하고 있음을 느낄 수 있도록 해주었습니다.

1.2. 메니페스트 설정

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="lilcode.aop.p2.c08.simplewebbrowser">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SimpleWebBrowser"
        android:usesCleartextTraffic="true">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

메니페스트의 경우에는 인터넷 권한을 사용하기 때문에 관련 권한을 설정하는 속성 를 추가해주어야 합니다.

그리고 보안 관려해서 https를 사용하여야 하지만 http 또한 허용하도록 android:usesCleartextTraffic="true" 속성을 추가해주었습니다.

2. 웹 뷰 사용하기

웹 뷰를 초기화 할 때 웹뷰 클라이언트와, 웹 크롬클라이언트를 할당해주고 (해당 프로젝트에서는 이너 클래스 사용) 웹페이지를 원활하게 사용하기 위해서 자바스크립트를 사용 가능 하도록 허용 해주도록 합니다.

    private fun initViews() {
        webView.apply {
            webViewClient = WebViewClient()
            webChromeClient = WebChromeClient()
            settings.javaScriptEnabled = true // 자바 스크립트 사용 가능 하도록
            loadUrl(HOME_URL)
        }
    }

loadUrl 을 통해서 초기 실행시에는 정해 놓은 홈페이지로 이동 하도록 해주었습니다. (구글 홈으로 이동하게됨)

    companion object {
        private const val HOME_URL = "http://www.google.com"
    }

이후에 SwipeRefreshLayoutContentLoadingProgressBar 를 보다 더 적절하게 사용하기 위해서 WebViewClientWebChromeClient 를 상속한 클래스를 따로 작성하여 필요한 부분을 오버라이딩 하여 사용하도록 했습니다. (아래)

2.1. WebViewClient webChromeClient

    inner class WebViewClient: android.webkit.WebViewClient(){

        // 페이지가 다 로딩 되었을때
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)

            refreshLayout.isRefreshing = false

            progressBar.hide()

            goBackButton.isEnabled = webView.canGoBack()
            goForwardButton.isEnabled = webView.canGoForward()
            addressBar.setText(url)
        }


        // 시작 시
        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            super.onPageStarted(view, url, favicon)

            progressBar.show()
        }

    }

먼저 웹뷰 클라이언트 입니다. SwipeRefreshLayout 을 통해 새로고침 할 때 페이지가 로딩이 시작될 경우 프로그레스바가 보이도록 해주고 로딩이 모두 완료 되었을 경우에는 새로고침 중이 아님을 확인하고 프로그레스바를 숨깁니다.

뒤로 가기와 앞으로 가기의 경우에도 가능한 경우에만 버튼이 활성화 되도록 페이지가 로드 되었을 때 확인하여 활성화 여부를 결정하고있습니다.

클래스 선언 시에는 inner class 로 선언하여 현재 메인 엑티비티 클래스 내부 멤버에도 접근이 가능하도록 해주어야 합니다.

    inner class WebChromeClient: android.webkit.WebChromeClient(){

        // 페이지 로딩 정도 0~100
        override fun onProgressChanged(view: WebView?, newProgress: Int) {
            super.onProgressChanged(view, newProgress)

            progressBar.progress = newProgress
        }
    }

마찬 가지로 WebChromeClient 또한 정의 해주는데 여기서 정의해줄 내용은 progressBar 에서 사용 될 진행도를 받아오는 용도로 onProgressChanged를 오버라이드 하여 newProgress 를 그대로 progress 속성에 대입해주면 됩니다.

2.2. 뒤로가기(back) 버튼 리스너 재정의

    override fun onBackPressed() {

        if(webView.canGoBack()){
            webView.goBack()
        }
        else{
            super.onBackPressed()
        }
    }

앱에서 뒤로가기 버튼을 누르면 바로 종료되는 것이 아니라 웹 뷰에서 뒤로 가기가 가능한 경우의 뒤로 가기 기능을 수행하고 뒤로가기가 불가능 한 경우에만 앱을 종료할 수 있도록 onBackPressed 함수를 재정의 해줍니다.

2.3. 웹 뷰 기타 기능 구현

        // 뒤로가기 버튼
        goBackButton.setOnClickListener {
            webView.goBack() // 뒤로 가기
        }

        // 앞으로 가기 버튼
        goForwardButton.setOnClickListener {
            webView.goForward()
        }

        // 홈 버튼
        goHomeButton.setOnClickListener {
            webView.loadUrl(HOME_URL)
        }

뒤로, 앞으로 가기 버튼 기능과 홈 버튼 기능을 구현하는 코드입니다.

3. SwipeRefreshLayout

앱을 사용하다 보면 위에서 아래로 당겼을 때 동그란 로딩창이 돌면서 새로고침을 수행하는 기능이 있는데 그 기능을 구현할 수 있는 레이아웃이 SwipeRefreshLayout 입니다. 사용 법은 간단합니다.

        // 리프레시 레이아웃
        refreshLayout.setOnRefreshListener {
            webView.reload() // 새로 고침
        }

스크롤 가능한 뷰를 리프레시 레이아웃에 포함시키고 setOnRefreshListener 를 재정의 해서 위에서 아래로 쓸었을 때 어떤 기능을 수행할지 정해주면 됩니다. 여기서는 웹뷰의 새로고침(reload)을 수행하도록 정의했습니다.

4. 기타

  • 주소창(EditText) 선택 시 전체 선택 되도록 하기

android:selectAllOnFocus="true" 속성을 통해서 포커스가 아웃된 상태에서 다시 포커스가 잡히면 텍스트가 전체선택 되도록 할 수 있습니다.

  • 주소창 Enter 시 주소검사 및 키보드 내리기
addressBar.setOnEditorActionListener { v, actionId, event ->
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                val loadingUrl = v.text.toString()

                if (URLUtil.isNetworkUrl(loadingUrl)){
                    webView.loadUrl(loadingUrl)
                }else{
                    webView.loadUrl("http://$loadingUrl")
                }
            }

            return@setOnEditorActionListener false // 키보드 닫기까지 동작 하도록
        }

setOnEditorActionListener 를 설정 시 주소를 검사하는데 이는 URLUtil 을 사용해서 isNetworkUrl 으로 실제 url이 맞는지 체크하고 아닐 경우에는 http:// 를 강제로 붙여주어 웹뷰에 로드하도록 해주었습니다.

그리고 return 시 false 를 반환하여 키보드 닫기 까지 수행합니다. (false 반환 시 더이상 처리할 것 없다는 것으로 판단하여 키보드 내려주는 듯)

  • 상태창 색상 변경

<color name="transparent">#00000000</color>

상태창의 경우에는 투명하게 지정해서 배경과 동일한 색상을 가지도록 설정 해줄 수 있습니다.

해당 프로젝트의 전체 내용과 보다 상세한 코드가 궁금하신 분은 저의 깃허브 저장소를 방문하시면 확인가능하십니다.

댓글
최근에 올라온 글
최근에 달린 댓글
네이버 이웃추가
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함