diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index b651560200ce422f16f0e6e1da87daafa3a933aa..81ac21ab38b91a353642be2eaa8c0c312531a57b 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -44,6 +44,8 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { // スワイプのジェスチャー。折に触れて状態設定をする必要があるのでメンバーとして持つ。 // 必要とされるタイミング次第で null のままのことがある恐れがあるので lateinit にはしていない。 private var swipeGestureListener: SwipeGestureListener? = null + // ピンチのジェスチャー。 + private var pinchGestureListener: PinchGestureListener? = null private val baseViewModel by activityViewModels() @@ -162,13 +164,19 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { // スワイプによるページ遷移設定 webview?.let { - val listener = SwipeGestureListener(it) + val listener = SwipeGestureListener() swipeGestureListener = listener + val pinchListener = PinchGestureListener(it) + pinchGestureListener = pinchListener + // GestureListener による onScroll では実際にページのスクロールがされたか分からないので WebView 側のイベントを拾う。 it.setOnScrollChangeListener { _, scrollX, _, oldScrollX, _ -> listener.recordScroll(scrollX, oldScrollX) } val gestureDetector = GestureDetectorCompat(requireContext(), listener) + // ピンチの検知 + val pinchDetector = ScaleGestureDetector(requireContext(), pinchListener) + it.setOnTouchListener { _, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { @@ -178,7 +186,13 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { swipeControl.updateSwipeRefreshState(it.scrollY == 0) } } - gestureDetector.onTouchEvent(event) + // タップしている指が1本ならGestureDetectorを呼ぶ + if (event.getPointerCount() == 1){ + gestureDetector.onTouchEvent(event) + } else { + // それ以外ならピンチ + pinchDetector.onTouchEvent(event) + } } it.isFocusableInTouchMode = true @@ -186,7 +200,7 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { } } - private class SwipeGestureListener(private val webView: WebView) : GestureDetector.SimpleOnGestureListener() { + private class SwipeGestureListener() : GestureDetector.SimpleOnGestureListener() { // 速度が SWIPE_VX, y 方向との比が SWIPE_RACIO 以上の時に横スワイプとみなす val SWIPE_VX = 200.0 val SWIPE_RATIO = 2.0 @@ -226,6 +240,52 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { return false } } + // ピンチを検知した際の処理 + private class PinchGestureListener(private val webView: WebView): ScaleGestureDetector.SimpleOnScaleGestureListener(){ + // ピンチアウト時のjavascript + val pinchOutDomCode = "javascript:(function(){document.getElementById('mobile-zoom-in').click();})()" + // ピンチイン時のjavsscript + val pinchInDomCode = "javascript:(function(){document.getElementById('mobile-zoom-out').click();})()" + // ピンチするかしないかの閾値 + var pinchThreshold = 0.0F + // ピンチ判定の基準値 + val pinchStandard = 1.0F + + override fun onScale(detector: ScaleGestureDetector): Boolean { + // 基準値とピンチの拡大縮小率の差を計算 + // detector.getScaleFactorで取得する値はonScaleが処理した直前の拡大縮小率を1としていて、 + // 1との差分の総和が全体の拡大縮小率となるので、計算して保持する + pinchThreshold += detector.getScaleFactor() - pinchStandard + // 拡大縮小率の総和が、0.25よりも大きければピンチアウト + // 0.25、-0.25は実機にて動作を確認して決定 + if (pinchThreshold > 0.25) { + // 総和の初期化 + pinchThreshold = 0.0F + executePinchJavascript(pinchOutDomCode) + return true + } + // 拡大縮小率の総和が、-0.25よりも小さければピンチイン + else if (pinchThreshold < -0.25) { + // 総和の初期化 + pinchThreshold = 0.0F + executePinchJavascript(pinchInDomCode) + return true + } + return false + } + // ピンチが終わった際に閾値初期化 + override fun onScaleEnd(detector: ScaleGestureDetector?) { + pinchThreshold = 0.0F + } + + private fun executePinchJavascript(domCode: String){ + webView?.evaluateJavascript(domCode) { result -> + if (result == "null") { + return@evaluateJavascript + } + } + } + } private fun getSessionAndSetupWebView(view: View, url: String, lasturl: String?, urlLoading: Boolean) { CookieManager.getInstance().apply {