Skip to content

Commit 0aacc8f

Browse files
author
mert.yuksel
committed
Remove unserializable properties in the DialogFragmentArguments class.
To configure a WebView inside a DialogFragment and make it as flexible as possible without copying and pasting every function that WebView has, this pull request makes DialogFragment rely on Configurator Fragments which implement the WebViewDownloadConfigurator and WebViewConfigurator interfaces. I chose to use fragments to configure the inner WebView because configurator fragments will be re-instantiated after a configuration change, and Android developers are accustomed to avoiding memory leaks.
1 parent 8729b23 commit 0aacc8f

File tree

9 files changed

+149
-40
lines changed

9 files changed

+149
-40
lines changed

libraries/dialogs/src/main/java/com/trendyol/uicomponents/dialogs/Builder.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,8 @@ open class InfoDialogBuilder internal constructor() : Builder() {
3131
var showContentAsHtml: Boolean = false
3232
var contentTextPosition: TextPosition? = null
3333
var webViewContent: WebViewContent? = null
34-
var webViewBuilder: (WebView.() -> Unit)? = null
3534
var horizontalPadding: Float? = null
3635
var verticalPadding: Float? = null
37-
var webViewDownloadListener: DownloadListener? = null
3836

3937
internal fun buildInfoDialog(block: InfoDialogBuilder.() -> Unit): DialogFragment {
4038
return InfoDialogBuilder().apply(block).let {
@@ -56,12 +54,10 @@ open class InfoDialogBuilder internal constructor() : Builder() {
5654
titleTextPosition = it.titleTextPosition,
5755
contentTextPosition = it.contentTextPosition,
5856
webViewContent = it.webViewContent,
59-
webViewBuilder = it.webViewBuilder,
6057
isFullHeightWebView = it.isFullHeightWebView
6158
).toBundle()
6259
this.closeButtonListener = it.closeButtonListener ?: { }
6360
this.onDismissListener = it.onDialogDismissListener ?: {}
64-
this.webViewDownloadListener = it.webViewDownloadListener
6561
}
6662
}
6763
}

libraries/dialogs/src/main/java/com/trendyol/uicomponents/dialogs/DialogFragment.kt

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,21 @@ import android.text.method.LinkMovementMethod
88
import android.text.util.Linkify
99
import android.view.LayoutInflater
1010
import android.view.View
11+
import android.view.ViewConfiguration
1112
import android.view.ViewGroup
1213
import android.view.ViewOutlineProvider
1314
import android.webkit.DownloadListener
1415
import android.webkit.WebChromeClient
1516
import android.webkit.WebViewClient
1617
import androidx.core.widget.doAfterTextChanged
18+
import androidx.fragment.app.Fragment
1719
import androidx.fragment.app.FragmentManager
1820
import androidx.lifecycle.ViewModelProviders
1921
import com.google.android.material.bottomsheet.BottomSheetBehavior
2022
import com.trendyol.dialog.R
2123
import com.trendyol.dialog.databinding.FragmentDialogBinding
24+
import com.trendyol.uicomponents.dialogs.configurator.WebViewConfigurator
25+
import com.trendyol.uicomponents.dialogs.configurator.WebViewDownloadConfigurator
2226
import com.trendyol.uicomponents.dialogs.list.DialogListAdapter
2327
import com.trendyol.uicomponents.dialogs.list.DialogListViewModel
2428
import com.trendyol.uicomponents.dialogs.list.ItemDecorator
@@ -193,8 +197,8 @@ class DialogFragment internal constructor() : BaseBottomSheetDialog() {
193197
if (visibility == View.VISIBLE) {
194198
webChromeClient = WebChromeClient()
195199
webViewClient = WebViewClient()
196-
dialogArguments.webViewBuilder?.invoke(webViewContent)
197-
200+
findWebViewConfigurator(requireFragmentManager())
201+
?.configureWebView(webViewContent)
198202
loadWebViewContent(viewState.webViewContent)
199203
if (dialogArguments.isFullHeightWebView) {
200204
binding.webViewContent.layoutParams.height =
@@ -219,8 +223,31 @@ class DialogFragment internal constructor() : BaseBottomSheetDialog() {
219223
}
220224
}
221225

222-
fun showDialog(fragmentManager: FragmentManager) {
223-
show(fragmentManager, TAG)
226+
fun showDialog(
227+
fragmentManager: FragmentManager,
228+
) {
229+
showDialog(fragmentManager, null, null)
230+
}
231+
232+
fun <ViewConfigurator, DownloadConfigurator> showDialog(
233+
fragmentManager: FragmentManager,
234+
webViewConfigurator: ViewConfigurator?,
235+
downloadConfigurator: DownloadConfigurator?,
236+
) where DownloadConfigurator : Fragment,
237+
DownloadConfigurator : WebViewDownloadConfigurator,
238+
ViewConfigurator : Fragment,
239+
ViewConfigurator : WebViewConfigurator {
240+
241+
val transaction = fragmentManager.beginTransaction()
242+
with(transaction) {
243+
if (webViewConfigurator != null) {
244+
transaction.add(webViewConfigurator, WebViewConfigurator.TAG)
245+
}
246+
if (downloadConfigurator != null) {
247+
add(downloadConfigurator, WebViewDownloadConfigurator.TAG)
248+
}
249+
}
250+
show(transaction, TAG)
224251
}
225252

226253
private fun setUpViewModel(items: List<Pair<Boolean, CharSequence>>) {
@@ -252,14 +279,29 @@ class DialogFragment internal constructor() : BaseBottomSheetDialog() {
252279

253280
override fun onResume() {
254281
super.onResume()
255-
binding.webViewContent.setDownloadListener(webViewDownloadListener)
282+
findWebViewDownloadConfigurator(requireFragmentManager())
283+
?.configureDownloadListener(binding.webViewContent)
256284
}
257285

258286
override fun onPause() {
259287
super.onPause()
260288
binding.webViewContent.setDownloadListener(null)
261289
}
262290

291+
private fun findWebViewDownloadConfigurator(
292+
fragmentManager: FragmentManager
293+
): WebViewDownloadConfigurator? {
294+
val fragment = fragmentManager.findFragmentByTag(WebViewDownloadConfigurator.TAG)
295+
return fragment as? WebViewDownloadConfigurator
296+
}
297+
298+
private fun findWebViewConfigurator(
299+
fragmentManager: FragmentManager
300+
): WebViewConfigurator? {
301+
val fragment = fragmentManager.findFragmentByTag(WebViewConfigurator.TAG)
302+
return fragment as? WebViewConfigurator
303+
}
304+
263305
companion object {
264306

265307
const val TAG: String = "TRENDYOL_BOTTOM_SHEET_DIALOG"

libraries/dialogs/src/main/java/com/trendyol/uicomponents/dialogs/DialogFragmentArguments.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ class DialogFragmentArguments(
3737
val titleTextPosition: TextPosition? = null,
3838
val contentTextPosition: TextPosition? = null,
3939
val webViewContent: WebViewContent? = null,
40-
val webViewBuilder: (WebView.() -> Unit)? = null,
4140
val infoListItems: List<Pair<CharSequence, CharSequence>>? = null,
4241
val itemDividers: List<ItemDivider> = emptyList(),
4342
val isFullHeightWebView : Boolean = false
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.trendyol.uicomponents.dialogs.configurator
2+
3+
import android.webkit.WebView
4+
5+
interface WebViewConfigurator {
6+
7+
fun configureWebView(webView: WebView)
8+
9+
companion object {
10+
const val TAG: String = "WebViewConfigurator"
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.trendyol.uicomponents.dialogs.configurator
2+
3+
import android.webkit.WebView
4+
5+
interface WebViewDownloadConfigurator {
6+
7+
fun configureDownloadListener(webView: WebView)
8+
9+
companion object {
10+
const val TAG: String = "WebViewDownloadConfigurator"
11+
}
12+
}

sample/src/main/java/com/trendyol/uicomponents/DialogsActivity.kt

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
package com.trendyol.uicomponents
22

3-
import android.app.DownloadManager
43
import android.graphics.Color
5-
import android.net.Uri
64
import android.os.Bundle
7-
import android.os.Environment
85
import android.text.SpannableString
96
import android.text.SpannableStringBuilder
10-
import android.webkit.DownloadListener
11-
import android.webkit.URLUtil
127
import android.webkit.WebViewClient
138
import android.widget.Toast
149
import androidx.appcompat.app.AppCompatActivity
@@ -30,9 +25,6 @@ class DialogsActivity : AppCompatActivity() {
3025

3126
private lateinit var binding: ActivityDialogsBinding
3227

33-
private val downloadManager: DownloadManager? by lazy(LazyThreadSafetyMode.NONE) {
34-
getSystemService(DOWNLOAD_SERVICE) as? DownloadManager
35-
}
3628

3729
override fun onCreate(savedInstanceState: Bundle?) {
3830
super.onCreate(savedInstanceState)
@@ -152,12 +144,11 @@ class DialogsActivity : AppCompatActivity() {
152144
closeButtonListener = infoDialogClosed
153145
webViewContent =
154146
WebViewContent.UrlContent("https://github.com/Trendyol/android-ui-components")
155-
webViewBuilder = {
156-
settings.javaScriptEnabled = true
157-
settings.domStorageEnabled = true
158-
webViewClient = WebViewClient()
159-
}
160-
}.showDialog(supportFragmentManager)
147+
}.showDialog(
148+
fragmentManager = supportFragmentManager,
149+
webViewConfigurator = WebViewDomAndJSEnabler(),
150+
downloadConfigurator = null,
151+
)
161152
}
162153

163154
private fun showInfoListDialog() {
@@ -189,21 +180,13 @@ class DialogsActivity : AppCompatActivity() {
189180
showContentAsHtml = true
190181
titleTextColor = CardInputViewR.color.civ_error_stroke
191182
showCloseButton = true
192-
webViewBuilder = {
193-
settings.javaScriptEnabled = true
194-
}
195-
webViewDownloadListener = DownloadListener { url, _, contentDisposition, mimetype, _ ->
196-
val downloadRequest = DownloadManager.Request(Uri.parse(url))
197-
.setTitle(title)
198-
.setMimeType(mimetype)
199-
.setDestinationInExternalPublicDir(
200-
Environment.DIRECTORY_DOWNLOADS,
201-
URLUtil.guessFileName(url, contentDisposition, mimetype)
202-
)
203-
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
204-
downloadManager?.enqueue(downloadRequest)
205-
}
206-
}.showDialog(supportFragmentManager)
183+
}.showDialog(
184+
fragmentManager = supportFragmentManager,
185+
webViewConfigurator = WebViewJavascriptEnabler(),
186+
downloadConfigurator = WebViewDownloadListenerConfigurator.newInstance(
187+
"Info Dialog with WebView Download Listener"
188+
)
189+
)
207190
}
208191

209192
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
@@ -272,4 +255,4 @@ class DialogsActivity : AppCompatActivity() {
272255
private fun showToast(message: String) {
273256
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
274257
}
275-
}
258+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.trendyol.uicomponents
2+
3+
import android.webkit.WebViewClient
4+
import androidx.fragment.app.Fragment
5+
import com.trendyol.uicomponents.dialogs.configurator.WebViewConfigurator
6+
7+
class WebViewDomAndJSEnabler : WebViewConfigurator, Fragment() {
8+
override fun configureWebView(webView: android.webkit.WebView) {
9+
webView.settings.javaScriptEnabled = true
10+
webView.settings.domStorageEnabled = true
11+
webView.webViewClient = WebViewClient()
12+
}
13+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.trendyol.uicomponents
2+
3+
import android.app.DownloadManager
4+
import android.net.Uri
5+
import android.os.Environment
6+
import android.webkit.DownloadListener
7+
import android.webkit.URLUtil
8+
import android.webkit.WebView
9+
import androidx.core.content.ContextCompat
10+
import androidx.core.os.bundleOf
11+
import androidx.fragment.app.Fragment
12+
import com.trendyol.uicomponents.dialogs.configurator.WebViewDownloadConfigurator
13+
14+
class WebViewDownloadListenerConfigurator : WebViewDownloadConfigurator, Fragment() {
15+
private val downloadManager: DownloadManager? by lazy(LazyThreadSafetyMode.NONE) {
16+
ContextCompat.getSystemService(requireContext(), DownloadManager::class.java)
17+
}
18+
19+
override fun configureDownloadListener(webView: WebView) {
20+
webView.setDownloadListener(DownloadListener { url, _, contentDisposition, mimetype, _ ->
21+
val downloadRequest = DownloadManager.Request(Uri.parse(url))
22+
.setTitle(requireArguments().getString("title"))
23+
.setMimeType(mimetype)
24+
.setDestinationInExternalPublicDir(
25+
Environment.DIRECTORY_DOWNLOADS,
26+
URLUtil.guessFileName(url, contentDisposition, mimetype)
27+
)
28+
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
29+
downloadManager?.enqueue(downloadRequest)
30+
})
31+
}
32+
33+
companion object {
34+
fun newInstance(title: String): WebViewDownloadListenerConfigurator =
35+
WebViewDownloadListenerConfigurator().apply {
36+
this.arguments = bundleOf("title" to title)
37+
}
38+
}
39+
40+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.trendyol.uicomponents
2+
3+
import android.webkit.WebView
4+
import androidx.fragment.app.Fragment
5+
import com.trendyol.uicomponents.dialogs.configurator.WebViewConfigurator
6+
7+
class WebViewJavascriptEnabler : WebViewConfigurator, Fragment() {
8+
9+
override fun configureWebView(webView: WebView) {
10+
webView.settings.javaScriptEnabled = true
11+
}
12+
}

0 commit comments

Comments
 (0)