Blog スタッフブログ

Android システム開発

[Android][Kotlin]WebViewの下Swipe更新実装

システム開発担当のTFです。

※Android10対応(他バージョンの場合、細かい部分等が異なる事があります)

やり方

  • swiperefreshlayout の依存関係を追加する
  • レイアウトにSwipeRefreshLayoutをおき、その中にWebViewを格納するためのLayoutを設置する
  • activity内で、Swipe更新処理を制御したWebViewを生成する

参考

  【Android】WebViewのスワイプによる再読み込みを実装【SwipeRefreshLayout】
  WebViewをSwipeRefreshLayoutやViewPager等に配置し、NestedScrollできるようにする方法
  HorizontalScrollViewのスクロール中にSwipeRefreshLayoutのリフレッシュが干渉する問題

サンプル

dependencies {

	// swiperefreshlayout を追加する
	implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

			<!-- この中にWebViewを入れる -->
            <FrameLayout
                android:id="@+id/container"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class MainActivity : AppCompatActivity() {

	// WebView用の変数
	lateinit var webView : WebView
	// Swipe更新可能状態の保存
	var swipeRefreshFlg: Boolean = false
	
	override fun onCreate(savedInstanceState: Bundle?) {
		// 省略
		
		// WebViewの作成
		webView = object : WebView(context){
			override fun onOverScrolled(scrollX: Int, scrollY: Int, clampedX: Boolean, clampedY: Boolean) {
				super.onOverScrolled(scrollX, scrollY, clampedX, clampedY)

				// 縦スクロールが発生しない状態でのスクロール( 端の状態 )
				if( clampedY ){
					swipeRefreshFlg = true
				}
			}
		}
		// タッチ判定
		webView.setOnTouchListener { v, event ->
			when(event.action){
				// タッチ終了
				MotionEvent.ACTION_UP -> {
					swipeRefreshFlg = false
				}
			}
			false
		}
		
		// 作成したWebViewをcontainerに格納する
		binding.container.addView(webView)
		
		
		// 引っ張って更新
        binding.swipeRefresh.setOnRefreshListener {
            // リロード
			webView.reload()
			// 引っ張った際のグルグル表示を止める
            binding.swipeRefresh.isRefreshing = false
        }
        // childのスクロール対応
        binding.swipeRefresh.setOnChildScrollUpCallback { parent, child ->
            // 画面上端で、Swipe更新可能か
			webView.scrollY != 0 || !swipeRefreshFlg
        }
		
	}
}