引っ張ったらViewを少しずつ小さくしてしきい値を超えたら閉じるっていうWebViewFragment作った。
こんなの。
ベースはこのクラス使ったw
ってことで実装。
実装
ジェスチャーを検知できるWebViewを作成
class ObservableWebView : WebView {
interface OnScrollChangedListener {
fun onScroll(l: Int, t: Int)
}
private var gd: GestureDetector? = null
private var listener: GestureDetector.SimpleOnGestureListener? = null
private var scrollChangedListener: OnScrollChangedListener? = null
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttrs: Int) : super(context, attrs, defStyleAttrs)
override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
super.onScrollChanged(l, t, oldl, oldt)
scrollChangedListener?.onScroll(l, t)
}
fun setListener(listener: GestureDetector.SimpleOnGestureListener) {
this.listener = listener
gd = GestureDetector(context, listener)
}
fun setOnScrollChangedCallback(onScrollChangedListener: OnScrollChangedListener) {
scrollChangedListener = onScrollChangedListener
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
gd?.onTouchEvent(event)
return super.onTouchEvent(event)
}
}
雑だけどw
基本的には↑に乗せてる記事と一緒で、ジェスチャーイベントを検知できるようにしただけ。
Fragmentのレイアウトファイル
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/backgroundLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#77777777">
<FrameLayout
android:id="@+id/topLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<hoge.package.view.ObservableWebView
android:id="@+id/webView"
android:overScrollMode="never"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/closeImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:src="@drawable/icon_web_close" />
</FrameLayout>
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
スケールを小さくするようのViewの下にWebViewを置く感じ。
WebViewを直接操作したらタッチ位置がずれるのかガクガクした。。。ような気もした。
もっと良いレイアウト構成あったら教えてほしい。
引っ張って小さくする、そして閉じる
//
view.webView.apply {
webChromeClient = WebChromeClient()
webViewClient = object : WebViewClient() {
override fun onPageStarted(webiew: WebView?, url: String?, favicon: Bitmap?) {
view.progressBar.visibility = View.VISIBLE
super.onPageStarted(webiew, url, favicon)
}
override fun onPageFinished(webview: WebView?, url: String?) {
super.onPageFinished(webview, url)
view.progressBar.visibility = View.INVISIBLE
}
}
settings.apply {
javaScriptEnabled = true
isVerticalFadingEdgeEnabled = false
isVerticalScrollBarEnabled = false
}
isFocusable = false
setOnScrollChangedCallback(object : ObservableWebView.OnScrollChangedListener {
override fun onScroll(l: Int, t: Int) {
webViewScrollOffset = t
}
})
setListener(object : GestureDetector.SimpleOnGestureListener() {
override fun onDown(e: MotionEvent?): Boolean {
oldY = e?.y ?: 0f
return true
}
override fun onScroll(e1: MotionEvent?, e2: MotionEvent?, distanceX: Float, distanceY: Float): Boolean {
if (webViewScrollOffset > 0) return super.onScroll(e1, e2, distanceX, distanceY)
e2?.also {
val dest = it.y - oldY
if (dest > 0) {
val scale = 1 - (dest / 1000)
view.topLayout.scaleX = scale
view.topLayout.scaleY = scale
if (scale < 0.8) {
view.backgroundLayout.setBackgroundColor(
ContextCompat.getColor(
view.context,
android.R.color.transparent
)
)
activity?.onBackPressed()
}
} else {
view.topLayout.scaleX = 1f
view.topLayout.scaleY = 1f
}
}
return super.onScroll(e1, e2, distanceX, distanceY)
}
})
loadUrl(loadUrl)
}
onScrollを受信したらもりもりViewを縮小させて閾値超えたら閉じる。
とりあえずこれで動画のような動きにはなる。