김호쭈
DevForYou
김호쭈
전체 방문자
오늘
어제
  • 분류 전체보기 (321)
    • • 데이터베이스(DB) (9)
      • __SQL__ (9)
    • •알고리즘(Algorithm ) (117)
      • 문제풀이 (99)
      • 스터디 (14)
      • 알고리즘 팁 (4)
    • •Compter Science (57)
      • Operating System (25)
      • Computer Network (1)
      • Computer Vision (16)
      • Artificial Intelligence (14)
      • Software Technology (1)
    • • 독서 (36)
      • Design Pattern (24)
      • 객체지향의 사실과 오해 (1)
      • Object Oriented Software En.. (11)
    • • 개발 (26)
      • React (3)
      • node.js (6)
      • Django (11)
      • Spring boot (6)
    • • 개발Tip (4)
      • GitHub (0)
    • •프로젝트 (2)
      • 물물 (2)
    • •App (54)
      • 안드로이드 with Kotlin (50)
      • 코틀린(Kotiln) (4)
    • •회고 (8)
    • •취준일기 (3)
    • • 기타 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • Remote저장소
  • KMU_WINK
  • 로컬저장소
  • local저장소
  • GitHubDesktop
  • 깃허브데스크탑
  • ㄱ
  • 원격저장소

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김호쭈

DevForYou

[안드로이드&코틀린] 웹브라우저 만들기, WebViewSwipeRefreshLayout, ContentLoadingProgressBar, 뒤로가기 버튼 커스텀,  imeOptions
•App/안드로이드 with Kotlin

[안드로이드&코틀린] 웹브라우저 만들기, WebViewSwipeRefreshLayout, ContentLoadingProgressBar, 뒤로가기 버튼 커스텀, imeOptions

2022. 3. 28. 23:05

 이번에는 간단한 웹브라우저를 만들었다. 보기에는 진짜 크롬같다는 생각이 먼저 든다. 만들기 전에 내가 하나하나 다 구현해야 할 줄 알았는데, 이미 존재하는 웹브라우저(크롬)을 상속받아서 기능을 구현했다. 뭐 특별히 엄청난 코드를 작성하고, 네트워크쪽이나 보안을 신경쓰면서 만든 것은 아니지만, 이런 기능이 있다는 것이 신기했다. 또한 WebView를 처음으로 써봤는데 신기했다. 


 

# 결과물 미리보기

홈버튼, 뒤로가기 버튼, 앞으로가기 버튼, 주소입력창과 스크롤하여 새로고침 기능을 구현했다. 우리가 사용하는 브라우저처럼 검색했을때 주소가 주소창에 계속 바뀌는 기능과, 앞으로가기 뒤로가기버튼도, 갈 곳이 없다면 비활성화 되게 구현했다. 또한 핸드폰자체의 뒤로가기 버튼도 브라우저의 뒤로가기 버튼효과가 나도록 했다.

 

# 알게 된 것

  • WebView
  • SwipeRefreshLayout
  • ContentLoadingProgressBar
  • 핸드폰 뒤로가기 버튼 재정의
  • EditText - imeOptions

 

# WebView

공식문서에서의 설명

요약하면 주소표시줄 탐색컨트롤과 같이 브라우저에서 제공해주는 여러 편의기능을 제외하고, 오직 애플리케이션위에 웹페이지를 띄워주는 역할을 하는 것이라고 생각하면 좋을거 같다. 

 

## WebView ( XML )

XML은 별다른 특이점 없이 크기를 지정해주면 된다.

 

## WebView 사용하기

xml의 view를 연결 시켜 준 후

private val webView: WebView by lazy {
    findViewById(R.id.webView)
}

 

webViewClient와 webChromeClient를 만들어 준다. 각각의 Client는 어느정도 깊은 구현사항을 요구하느냐에 따라서 달라지는데, 정말 간다한건 webViewClinet만 사용할 수 있고, Chrome에서 사용하는거와 같은 기능들은 ChromeClinet를 사용해야한다. 강의에서는 해당 클라이언트를 inner Class로 별도로 정의했지만, 난 익명객체를 만드는 방법을 공부했었기 때문에 응용해볼 겸 사용했다. 

webView안에 속성(property)인 webViewClient에 별다른 값을 지정해주지 않으면 내가 정의한 Client을 사용하지 않고 기본 브라우저인 Chrome이 열리는 것을 확인 할 수 있었다.

private fun initWebView() {
    webView.apply {
    
    	// 페이지가 끝났을때 특정 이벤트를 정의하기 위해 익명객체 생성
        webViewClient = object : WebViewClient() {
            override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
                progressBar.show()
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                refreshLayout.isRefreshing = false
                progressBar.hide()
                backButton.isEnabled = webView.canGoBack()
                forwardButton.isEnabled = webView.canGoForward()
                uriEditText.setText(url)

            }
        }

		//로딩 창 구현 이벤트를 정의하기 위해 익명객체 생성
        webChromeClient = object : WebChromeClient() {
            override fun onProgressChanged(view: WebView?, newProgress: Int) {
                super.onProgressChanged(view, newProgress)
                progressBar.progress = newProgress
            }
        }
        settings.javaScriptEnabled = true
        loadUrl(DEFAULT_URI)
    }

    uriEditText.setText(DEFAULT_URI)
}

이후 웹 뷰에서도 자바스크립트 기능을 사용하기 위해 javaScriptEnabled속성의 true를 주었다. webView의 loadUrl은 해당 Url로 연결해주는 함수이다. 기본으로 정의한 URL를 연결 시켜 줬다.

 

## 버튼구현

홈 뒤로가기 앞으로가기 버튼은 webView자체에서 지원하기 때문에 간단한 함수만으로도 구현할 수 있었다.

homeButton.setOnClickListener {
    webView.loadUrl(DEFAULT_URI)
    uriEditText.setText(DEFAULT_URI)
}

forwardButton.setOnClickListener {
    webView.goForward()
}

backButton.setOnClickListener {
    webView.goBack()
}

 

# SwipeRefreshLayout으로 슬라이딩 새로고침

화면을 잡아댕겨 새로고침하는 것이 매우 어려울 줄 알았지만 제공하는 레이아웃이 있어서 활용할 수 있었다.

아래와 같이 WebView를 SwipeRefreshLayout안에다가 넣어주면 된다.

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
  android:id="@+id/refreshLayout"
  android:layout_width="0dp"
  android:layout_height="0dp"
  app:layout_constraintBottom_toBottomOf="parent"
  app:layout_constraintEnd_toEndOf="parent"
  app:layout_constraintStart_toStartOf="parent"
  app:layout_constraintTop_toBottomOf="@id/toolbar">

  <WebView
    android:id="@+id/webView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

build.gradle에 종속성을 추가해준다.

dependencies{
	implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
}

이후 view를 연결시켜준 후

private val refreshLayout : SwipeRefreshLayout by lazy {
    findViewById(R.id.refreshLayout)
}

setOnRefreshListener에 대해서 동작을 정의해 주면 됐다.

refreshLayout.setOnRefreshListener {
    webView.reload()
}

 

 

# ContentLoadingProgressBar

브라우저가 열리고 url이 바뀔때 상태에 대한 로딩바이다. 당연히 처음부터 구현할 필요는 없었고, 위에서 말했던것처럼 ChromeClient를 이용하면 된다.

webChromeClient = object : WebChromeClient() {
    override fun onProgressChanged(view: WebView?, newProgress: Int) {
        super.onProgressChanged(view, newProgress)
        progressBar.progress = newProgress
    }

 onProgressChanged를 재정의 해주자. inner Class르 객체를 만들어서 사용해도 무관하다. 인자로 넘어오는 newProgress는 현재 프로그래스진행사항을 Int값으로 넘겨주기 때문에, 이것을 그대로 progressBar.progress에 속성값으로 사용하면 됐다.

 

# onBackPressed() : 핸드폰 뒤로가기 버튼 재정의

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

마치 LifeCycle을 이용하듯 onBackPressed을 override하여 사용하면 된다.

 

 

# EditText - imeOptions

EditText는 키패드를 통하여 사용자가 값을 입력하게 해주는 View이다 여기에는 imeOptions이라는 속성이 존재한다.

<EditText
	//...
  android:imeOptions="actionDone"
  	//...
 />

이 옵션에 빨간색 박스 속 확인버튼의 모양이 바뀐다.

그리고 setOnEditorActionListener를 이용하면 되는데, 여기서 저 버튼에 준 속성값이 actionId로 넘어오게 된다. 즉 키패드에서 확인(체크)버튼을 누르고 난 이후의 상황을 정의해줄 수 있다.

uriEditText.setOnEditorActionListener { v, actionId, event ->
    if (actionId == EditorInfo.IME_ACTION_DONE) {
        val curURL = v.text.toString()

        if (URLUtil.isNetworkUrl(curURL)){
            webView.loadUrl(curURL)
        }else {
            webView.loadUrl("http://$curURL")
        }
    }
    return@setOnEditorActionListener false
}

 


# 느낀점

 꽤 완성도 있어 보이지만 생각보다 간단했다. 코드의 흐름을 알 수 있었고, WebView를 사용해봐서 신기했다. 꽤 많은 속성들을 재정의해줄 수 있다는 것을 알게 된거 같았고 익명객체를 내 생각대로 응용해봤는데, 상황에 맞게 사용해본거 같아서 뿌듯했다. drawable을 만들면서 디자인을 자유자재로 해볼 줄 알아야 하는거 같았다.

 

안드로이드 공식문서

 

WebView에서 웹 앱 빌드  |  Android 개발자  |  Android Developers

WebView에서 웹 앱 빌드 웹 애플리케이션 또는 웹페이지만 클라이언트 애플리케이션의 일부로 제공하려는 경우 WebView를 사용하면 됩니다. WebView 클래스는 Android의 View 클래스의 확장으로, 웹페이

developer.android.com

 

저작자표시 (새창열림)

'•App > 안드로이드 with Kotlin' 카테고리의 다른 글

[안드로이드&코틀린] 푸시알림오는 알람 앱 만들기, as, alarmManger, pendingIntent, tag, data class get()예제  (0) 2022.04.03
[안드로이드&코틀린] 파이어베이스사용하여 알림보내기, Firebase Cloud Message, 범블비(bumblebee)버전에서 안드로이드 스튜디오 파이어베이스 연결하기, SDK설정 오류  (0) 2022.03.31
[안드로이드&코틀린] 녹음기 만들기, Enum, set(value), run{...}, companion object, MediaRecorder, MediaPlayer, 커스텀 View 만들기  (0) 2022.03.25
[안드로이드&코틀린] 뽀모도로 타이머 , SeekBar의 활용, soundPool을 사용한 효과음, 익명객체 활용하기, 문자열포맷팅, "%02d", 슬라이드 바  (0) 2022.03.23
[안드로이드&코틀린] 앨범 만들기#4, 갤러리에서 이미지 가져오기, 안드로이드 SAF(Storage Access Framework)  (0) 2022.03.21
    '•App/안드로이드 with Kotlin' 카테고리의 다른 글
    • [안드로이드&코틀린] 푸시알림오는 알람 앱 만들기, as, alarmManger, pendingIntent, tag, data class get()예제
    • [안드로이드&코틀린] 파이어베이스사용하여 알림보내기, Firebase Cloud Message, 범블비(bumblebee)버전에서 안드로이드 스튜디오 파이어베이스 연결하기, SDK설정 오류
    • [안드로이드&코틀린] 녹음기 만들기, Enum, set(value), run{...}, companion object, MediaRecorder, MediaPlayer, 커스텀 View 만들기
    • [안드로이드&코틀린] 뽀모도로 타이머 , SeekBar의 활용, soundPool을 사용한 효과음, 익명객체 활용하기, 문자열포맷팅, "%02d", 슬라이드 바
    김호쭈
    김호쭈
    공부하고 정리하고 기록하기

    티스토리툴바