【Kotlin/Android】ScrollViewをネスト(入れ子)して実装する方法!NestedScrollView

【Kotlin/Android】ScrollViewをネスト(入れ子)して実装する方法!NestedScrollView

この記事からわかること

  • Android Studio/Kotlinネスト(入れ子)されたScrollView実装方法
  • NestedScrollView使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

ScrollViewをネストするとスクロールできなくなる

AndroidでScrollViewの中にScrollViewを配置すると親のScrollViewはスクロールできまずが、子のScrollViewはスクロールできなくなってしまいます

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="200dp">

        </ScrollView>

</ScrollView>

ネストされたScrollViewをスクロールできるようにする方法

ネストされたScrollViewを動作するようにするためには以下の2つの方法があります。

  1. 子にNestedScrollViewを指定する
  2. 親にカスタムで拡張したScrollViewを指定する

子にNestedScrollViewを指定する

公式リファレンス:NestedScrollView

NestedScrollViewを使用することでネストされたScrollViewをスクロールできるようにすることが可能です。使用方法は簡単で子供側にあるScrollViewNestedScrollViewに置き換えるだけです。

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="200dp">

        </androidx.core.widget.NestedScrollView>

</ScrollView>
【Kotlin/Android】ScrollViewをネスト(入れ子)して実装する方法!

親にカスタムで拡張したScrollViewを指定する

NestedScrollViewを使用せずに親側のViewを変更することでネストされたScrollViewをスクロールできるようにするには親ScrollViewが子ScrollViewの縦方向のスクロールだけを許可するカスタムViewを実装します。

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.ScrollView

class CustomScrollView @JvmOverloads  constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ScrollView(context, attrs, defStyleAttr) {

    private var xDistance: Float = 0f  // X軸方向の移動距離を追跡するための変数
    private var yDistance: Float = 0f  // Y軸方向の移動距離を追跡するための変数
    private var lastX: Float = 0f  // 最後のX座標を記録するための変数
    private var lastY: Float = 0f  // 最後のY座標を記録するための変数

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                // タッチが開始された場合は、移動距離と座標をリセット
                xDistance = 0f
                yDistance = 0f
                lastX = ev.x
                lastY = ev.y
            }
            MotionEvent.ACTION_MOVE -> {
                // タッチが移動した場合は、移動距離を更新
                val curX: Float = ev.x
                val curY: Float = ev.y
                xDistance += Math.abs(curX - lastX)
                yDistance += Math.abs(curY - lastY)
                lastX = curX
                lastY = curY
                // Y方向の移動距離がX方向よりも大きい場合、親ScrollViewのスクロールを停止する
                if (yDistance > xDistance) {
                    return false
                }
            }
        }
        // それ以外の場合は、親ScrollViewに処理を委譲
        return super.onInterceptTouchEvent(ev)
    }
}

あとは以下のようにXML側でカスタムViewを親に設定するだけです。

<com.sample.scrolltest.CustomScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <View
            android:layout_width="match_parent"
            android:layout_height="400dp"
            android:background="#23527c" />

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="200dp">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="200dp"
                android:orientation="vertical">

                <View
                    android:layout_width="match_parent"
                    android:layout_height="200dp"
                    android:background="#dd6b24" />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="200dp"
                    android:background="#000000" />

                <View
                    android:layout_width="match_parent"
                    android:layout_height="200dp"
                    android:background="#FFF000" />

            </LinearLayout>

        </ScrollView>

        <View
            android:layout_width="match_parent"
            android:layout_height="400dp"
            android:background="#bd9907" />

    </LinearLayout>

</com.sample.scrolltest.CustomScrollView>
【Kotlin/Android】ScrollViewをネスト(入れ子)して実装する方法!

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index