Skip to content

Commit

Permalink
feat: 주소검색 기능구현 (#161)
Browse files Browse the repository at this point in the history
* refactor: 네이밍 컨벤션 적용

* build: webview 라이브러리 추가

* feat: 스크립트 실행위한 html파일 추가

* refactor: 인터페이스명 변경에 따른 변경

* feat: 주소검색 다이얼로그 레이아웃 작성

* feat: 주소검색 기능 구현

* style: lint적용

* refactor: 불필요한 코드 제거
  • Loading branch information
Namyunsuk authored Aug 4, 2024
1 parent adcc62b commit bdbcf7e
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 11 deletions.
3 changes: 3 additions & 0 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,7 @@ dependencies {

// Pagination
implementation("androidx.paging:paging-runtime-ktx:3.3.0")

// WebView
implementation("androidx.webkit:webkit:1.9.0")
}
60 changes: 60 additions & 0 deletions android/app/src/main/assets/html/address.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<script type="text/javascript">
const BRIDGE_CODE = "address_finder";

function send(address, zipCode){
window[BRIDGE_CODE].result(address); // 파라미터에서 우편번호는 제외시킴
}
</script>
<style>
html, body { width: 100%; height: 100%; background: #ffffff; padding: 0; margin: 0; }
div#layer { width: 100%; height: 100%; }
</style>
</head>
<body onload="load()">
<div id="layer"
style="display:block;position:fixed;overflow:hidden;z-index:1;-webkit-overflow-scrolling:touch;"></div>

<script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
// 우편번호 찾기 화면을 넣을 element
const el = document.getElementById('layer');

function load() {
new daum.Postcode({
oncomplete: function(data) {
let fullRoadAddr = data.roadAddress; // 도로명 주소 변수
let extraRoadAddr = ''; // 도로명 조합형 주소 변수

// 법정동명이 있을 경우 추가한다. (법정리는 제외)
// 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
if(data.bname.length > 0 && /[동|로|가]$/g.test(data.bname))
extraRoadAddr += data.bname;

// 건물명이 있고, 공동주택일 경우 추가한다.
if(data.buildingName.length > 0 && data.apartment === 'Y')
extraRoadAddr += (extraRoadAddr !== '' ? ', ' + data.buildingName : data.buildingName);

// 도로명, 지번 조합형 주소가 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
if(extraRoadAddr.length > 0) extraRoadAddr = ' (' + extraRoadAddr + ')';

// 도로명, 지번 주소의 유무에 따라 해당 조합형 주소를 추가한다.
if(fullRoadAddr.length > 0) fullRoadAddr += extraRoadAddr;

send(fullRoadAddr, data.zonecode);
},
width : '100%',
height : '100%'
}).embed(el);
}

window.addEventListener('orientationchange', () => {
load();
})
</script>
</body>
</html>

Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.zzang.chongdae.presentation.view.address

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.setFragmentResult
import androidx.webkit.WebViewAssetLoader
import com.zzang.chongdae.databinding.DialogAddressFinderBinding

class AddressFinderDialog : DialogFragment(), OnAddressClickListener {
private var _binding: DialogAddressFinderBinding? = null
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = DialogAddressFinderBinding.inflate(inflater, container, false)

return binding.root
}

override fun onViewCreated(
view: View,
savedInstanceState: Bundle?,
) {
super.onViewCreated(view, savedInstanceState)

initDialog()
initWebView()
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

private fun initDialog() {
dialog?.window?.apply {
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}
}

@SuppressLint("SetJavaScriptEnabled")
private fun initWebView() {
val assetLoader = webViewAssetLoader()

binding.wvAddress.run {
with(settings) {
javaScriptEnabled = true
allowFileAccess = false
allowContentAccess = false
}
addJavascriptInterface(
JavascriptInterface(this@AddressFinderDialog),
JS_BRIDGE,
)
webViewClient = AddressWebViewClient(assetLoader)
loadUrl("https://$DOMAIN/$PATH/html/address.html")
}
}

private fun webViewAssetLoader() =
WebViewAssetLoader.Builder()
.addPathHandler(
"/$PATH/",
WebViewAssetLoader.AssetsPathHandler(requireContext()),
)
.setDomain(DOMAIN)
.build()

override fun onClickAddress(address: String) {
setFragmentResult(ADDRESS_KEY, bundleOf(BUNDLE_ADDRESS_KEY to address))
dismiss()
}

companion object {
private const val JS_BRIDGE = "address_finder"
private const val DOMAIN = "address.finder.net"
private const val PATH = "assets"

const val ADDRESS_KEY = "address_key"
const val BUNDLE_ADDRESS_KEY = "address"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.zzang.chongdae.presentation.view.address

import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import androidx.webkit.WebViewAssetLoader
import androidx.webkit.WebViewClientCompat

class AddressWebViewClient(private val assetLoader: WebViewAssetLoader) :
WebViewClientCompat() {
override fun shouldInterceptRequest(
view: WebView?,
request: WebResourceRequest?,
): WebResourceResponse? {
return assetLoader.shouldInterceptRequest(request!!.url)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.zzang.chongdae.presentation.view.address

import android.os.Looper

class JavascriptInterface(private val onAddressClickListener: OnAddressClickListener) {
@android.webkit.JavascriptInterface
fun result(address: String) {
android.os.Handler(Looper.getMainLooper()).post {
onAddressClickListener.onClickAddress(address)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.zzang.chongdae.presentation.view.address

interface OnAddressClickListener {
fun onClickAddress(address: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import com.zzang.chongdae.databinding.FragmentHomeBinding
import com.zzang.chongdae.presentation.view.home.adapter.OfferingAdapter
import com.zzang.chongdae.presentation.view.offeringdetail.OfferingDetailActivity

class HomeFragment : Fragment(), OnArticleClickListener {
class HomeFragment : Fragment(), OnOfferingClickListener {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private lateinit var offeringAdapter: OfferingAdapter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.zzang.chongdae.presentation.view.home

interface OnArticleClickListener {
interface OnOfferingClickListener {
fun onClick(offeringId: Long)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import com.zzang.chongdae.databinding.ItemOfferingBinding
import com.zzang.chongdae.domain.model.Offering
import com.zzang.chongdae.presentation.view.home.OnArticleClickListener
import com.zzang.chongdae.presentation.view.home.OnOfferingClickListener

class OfferingAdapter(
private val onArticleClickListener: OnArticleClickListener,
private val onOfferingClickListener: OnOfferingClickListener,
) : PagingDataAdapter<Offering, OfferingViewHolder>(productComparator) {
override fun onCreateViewHolder(
parent: ViewGroup,
Expand All @@ -24,7 +24,7 @@ class OfferingAdapter(
holder: OfferingViewHolder,
position: Int,
) {
getItem(position)?.let { holder.bind(it, onArticleClickListener) }
getItem(position)?.let { holder.bind(it, onOfferingClickListener) }
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ package com.zzang.chongdae.presentation.view.home.adapter
import androidx.recyclerview.widget.RecyclerView
import com.zzang.chongdae.databinding.ItemOfferingBinding
import com.zzang.chongdae.domain.model.Offering
import com.zzang.chongdae.presentation.view.home.OnArticleClickListener
import com.zzang.chongdae.presentation.view.home.OnOfferingClickListener

class OfferingViewHolder(
private val binding: ItemOfferingBinding,
) : RecyclerView.ViewHolder(binding.root) {
fun bind(
offering: Offering,
onArticleClickListener: OnArticleClickListener,
onOfferingClickListener: OnOfferingClickListener,
) {
binding.offering = offering
binding.onArticleClickListener = onArticleClickListener
binding.onArticleClickListener = onOfferingClickListener
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import kotlinx.coroutines.launch
class OfferingDetailViewModel(
private val offeringId: Long,
private val offeringDetailRepository: OfferingDetailRepository,
) : ViewModel(), ParticipationClickListener {
) : ViewModel(), OnParticipationClickListener {
private val _offeringDetail: MutableLiveData<OfferingDetail> = MutableLiveData()
val offeringDetail: LiveData<OfferingDetail> get() = _offeringDetail

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.zzang.chongdae.presentation.view.offeringdetail

interface ParticipationClickListener {
interface OnParticipationClickListener {
fun onClickParticipation()
}
19 changes: 19 additions & 0 deletions android/app/src/main/res/layout/dialog_address_finder.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

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

</FrameLayout>
</layout>
2 changes: 1 addition & 1 deletion android/app/src/main/res/layout/item_offering.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<variable
name="onArticleClickListener"
type="com.zzang.chongdae.presentation.view.home.OnArticleClickListener" />
type="com.zzang.chongdae.presentation.view.home.OnOfferingClickListener" />

</data>

Expand Down

0 comments on commit bdbcf7e

Please sign in to comment.