커스텀 뷰(custom view) 구현

맞춤 보기



자식 View를 여러 곳에서 사용하는 경우,
처리를 독립적으로 하고 싶은 경우에 커스텀 뷰를 사용한다.

또한 아이 View를 표시하고 있는 동안은 뒤의 View에 터치를 전파시키지 않게 한다.

구현



Activity에 addView 할 대상의 부모 View 인 FrameLayout 유지

활동



activity_main.xml
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 子Viewが表示中、このScrollViewがスクロールされなければOK -->
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/gradation">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="1000dp"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="500dp"
                android:text="activity_main top"
                android:textSize="30sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="activity_main bottom"
                android:textSize="30sp" />
        </LinearLayout>

    </ScrollView>

    <!-- 親View -->
    <FrameLayout
        android:id="@+id/customViewContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 親View
        val container = findViewById<FrameLayout>(R.id.customViewContainer)

        // 子View
        val firstCustomView = FirstCustomView(this, {
            container.removeAllViews()    // 親Viewに設定した子Viewを削除
        })

        // 親Viewに子viewを設定
        container.addView(firstCustomView)
    }
}

커스텀 뷰 (하위 View)



widget_custom_view.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#66000000">

    <FrameLayout
        android:layout_gravity="center"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="@android:color/black">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="custom view first"
            android:textColor="@android:color/white"
            android:textSize="30sp" />

        <Button
            android:id="@+id/customFirstButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center"
            android:layout_marginBottom="30dp"
            android:text="close"
            android:textColor="@android:color/black" />
    </FrameLayout>

</FrameLayout>

FirstCustomView.kt
class FirstCustomView(context: Context): FrameLayout(context) {

    var onClick: (()->Unit)? = null

    constructor(context: Context, onClick: ()->Unit): this(context){
        this.onClick = onClick
    }

    init{
        // Viewを設定
        inflate(context, R.layout.widget_custom_first, this)

        findViewById<Button>(R.id.customFirstButton)?.setOnClickListener {
            onClick?.invoke()
        }

        // 背後のViewへタッチを伝搬させない
        // これがないと後ろのスクロールViewがスクロールできてしまう
        setOnTouchListener { _, _ -> true }
    }
}

결과



스크린샷

아이 뷰 표시시 - 스크롤 불가





CLOSE 탭하여 하위 View 삭제 후





스크롤 가능하게





설명



부모 View의 Container에 FrameLayout을 상속한 자식 View의 FirstCustomView를
addView()에서 설정
        // 親Viewに子viewを設定
        container.addView(firstCustomView)

자식 View의 "CLOSE"Button을 탭했을 때 Activity에 탭되었음을 통지
부모 View에서 removeAllView()에서 자식 View를 삭제.
        // 子View
        val firstCustomView = FirstCustomView(this, {
            container.removeAllViews()    // 親Viewに設定した子Viewを削除
        })

쓰기가 매우 좋기 때문에 중규모 이상의 앱에서 사용하면 좋은 느낌입니다.

좋은 웹페이지 즐겨찾기