こんにちは。kettsun0123です。
今回はタイトルの通り「Databindingでラムダ式渡したい!ってなったときにどうするか」っていう話です。
ラムダ式をdatabindingで渡したいってなったときに困ったのでメモがてら。
シチュエーション
- TextViewの一部がリンク
- リンクをクリックしたらurlを返り値としたい
- urlはChromeCustomTabsで開きたい
- ラムダ式でonLinkClick渡せたら気持ちよさそう
と、今回はこんなシチュでした。
ChromeCustomTabs
ChromeUtil.kt
object ChromeUtil {
fun showCustomTabs(activity: FragmentActivity, url: String) {
val packageName = CustomTabsHelper.getPackageNameToUse(activity)
val customTabsIntent = CustomTabsIntent.Builder().setShowTitle(true)
.setToolbarColor(ContextCompat.getColor(activity, R.color.colorPrimaryDark))
.build()
customTabsIntent.intent.`package` = packageName
customTabsIntent.launchUrl(activity, Uri.parse(url))
}
}
Activity側
HogeActivity.kt
...
private val onLinkClick: (String) -> Unit = {
ChromeUtil.showCustomTabs(activity!!, it)
}
...
Layoutファイル
さて、定義したラムダ式を渡します。
使うのは kotlin.jvm.functions.Function1
です。
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="onLinkClick"
type="kotlin.jvm.functions.Function1"
/>
</data>
...
</layout>
上記のように定義すればonLinkClick
でラムダ式を受けることができます。
Activity側からラムダ式渡す
HogeActivity.kt
private val onLinkClick: (String) -> Unit = {
ChromeUtil.showCustomTabs(activity!!, it)
}
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activityHogeBinding.?.let {
it.onLinkClick = onLinkClick
}
}
これで無事ラムダ式を渡せました
おまけ
今回の本題ではなかったのでおまけで。
ラムダ式はこんな感じで使いました↓↓
TextBindingAdapters.kt
@JvmStatic
@BindingAdapter("link_click", "link_text", "link_url")
fun bindLinkLambda(view: TextView, body: (String) -> Unit, text: String, url: String) {
val ss = SpannableString(view.text)
var start = 0
var end = 0
val matcher = Pattern.compile(text).matcher(view.text)
while (matcher.find()) {
start = matcher.start()
end = matcher.end()
break
}
ss.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint?) {
super.updateDrawState(ds)
ds?.let {
it.isUnderlineText = true
it.isFakeBoldText = true
}
}
override fun onClick(v: View) {
body(url)
}
}, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
view.text = ss
view.movementMethod = LinkMovementMethod.getInstance()
}