개발일지

Android in A..Z - View (CustomView-Extend) 본문

Android (안드로이드)/View

Android in A..Z - View (CustomView-Extend)

강태종 2021. 4. 30. 04:59

View와 ViewGroup을 상속받아서 직접 View를 만들 수 있지만 기존의 정의된 View나 ViewGroup을 상속 받아서 기능을 확장할 수 있다.


View 만들기

class LoginButtonView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) : MaterialCardView(context, attrs, defStyleAttr), DataBinding<ViewLoginButtonBinding> {
    override val binding: ViewLoginButtonBinding by lazy { DataBinding.get(this, R.layout.view_login_button) }

    init {
        context.theme.obtainStyledAttributes(attrs, R.styleable.LoginButtonView, defStyleAttr, defStyleRes).apply {
            if (isInEditMode) {
                inflate(context, R.layout.view_login_button, this@LoginButtonView)
                findViewById<TextView>(R.id.text_view).apply {
                    text = getString(R.styleable.LoginButtonView_text)
                    setTextColor(getColor(R.styleable.LoginButtonView_textColor, Color.parseColor("#000000")))
                }
                findViewById<ImageView>(R.id.icon_image_view).apply {
                    setImageDrawable(getDrawable(R.styleable.LoginButtonView_icon))
                }
            } else {
                with(binding) {
                    icon = getDrawable(R.styleable.LoginButtonView_icon)
                    text = getString(R.styleable.LoginButtonView_text)
                    textColor = getColor(R.styleable.LoginButtonView_textColor, Color.parseColor("#000000"))
                }
            }

            recycle()
        }
    }
}

isInEditMode는 편집기에서 실행되는지 나타내는 여부이며 AndroidStudioEditor에서 편집될 때 미리보기를 구현하려면 isInEditMode일 때 처리를 해야한다.

inflate함수를 통해서 XML로 정의한 View를 포함할 수 있다. (merge tag를 사용하면 Depth를 1개 줄일 수 있다.)


AttributeSet만들기

values에 attr.xml에 선언한다.

    <attr name="textColor" format="reference|color" />
    <attr name="icon" format="reference" />
    <attr name="text" format="reference|string" />
    <declare-styleable name="LoginButtonView">
        <attr name="icon" />
        <attr name="textColor" />
        <attr name="text" />
        <attr name="backgroundColor" format="reference|color" />
    </declare-styleable>

XML 만들기

layout에 view_login_button.xml를 추가한다.

<?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">

    <data>
        <variable
            name="icon"
            type="android.graphics.drawable.Drawable" />
        <variable
            name="text"
            type="String" />
        <variable
            name="textColor"
            type="Integer" />
    </data>

    <merge
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:parentTag="com.google.android.material.card.MaterialCardView">

        <LinearLayout
            android:clickable="true"
            android:focusable="true"
            android:foreground="?android:selectableItemBackground"
            android:padding="10dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            tools:ignore="UseCompoundDrawables">

            <ImageView
                android:id="@+id/icon_image_view"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_gravity="center"
                android:contentDescription="@string/icon"
                android:src="@{icon}"
                tools:src="@drawable/ic_google" />

            <TextView
                android:id="@+id/text_view"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center"
                android:text="@{text}"
                android:textColor="@{textColor}"
                android:textSize="18sp"
                tools:text="Google" />
        </LinearLayout>

    </merge>
</layout>

사용

            <com.taetae98.customview.view.LoginButtonView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                app:cardBackgroundColor="@color/white"
                app:icon="@drawable/ic_google"
                app:text="@string/google" />

            <com.taetae98.customview.view.LoginButtonView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="10dp"
                app:cardBackgroundColor="#FFEB00"
                app:icon="@drawable/ic_kakao"
                app:text="@string/kakao"
                app:textColor="#3C1E1E" />

Git (예제코드)

github.com/KangTaeJong98/Example/tree/main/Android/CustomView

 

KangTaeJong98/Example

My Example Code. Contribute to KangTaeJong98/Example development by creating an account on GitHub.

github.com

 

Comments