[Android]簡単な自作Viewを作った

#はじめに
簡単な自作Viewや独自Viewの作り方を初心者向けに説明していきたいと思います。
この記事で紹介する内容は下記に該当する方向けになっています。

###主なターゲット層
・Androidアプリ初心者の方

・自作Viewを作ったことがない方

・難しい言い回しをすっ飛ばして、自作Viewを簡単に作ってみたい方

###自作Viewを作る利点
今回の自作Viewを作る利点は以下のとおりです。

・独自にアレンジされた仕様のViewを使える点

・複数のViewで処理をする仕様をひとかたまりにして使える点


たとえば本来はできない、ButtonなどにClickListenerを複数追加することで自分なりにアレンジできる点など、その他もろもろの利点があると思います。自作Viewに取り組んだことがない方は是非取り組んでみてください。

#自作View作成の手順
自作Viewの作り方は様々で色々な作り方があるっぽいのですが、今回はできるだけシンプルで楽に作れる方法で紹介していきたいと思います。

まずは自作View作成の大まかな流れを紹介します。

流れとしては、

自作のViewのレイアウトをxmlで作成(フォルダーは/res/layout)
　　　　　↓
作成したxmlに機能を加えるJava or Kotlinクラスの作成
　　　　　↓
MainActivityで使用

上記の手順で元々あるViewたちを組み合わせたorアレンジしたオリジナルViewを作成していきます。

今回作成していく自作ViewはTextViewとButtonを組み合わせた以下のものを作成していきます。
![2FK9Cm1egITPNd7lZMXQ1575436894-1575437078.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288250/a2ed3fed-c873-c5c4-5eb8-1c4916706fab.gif)

###手順その1 自作Viewのレイアウトをxmlで作成
まずは/res/layout/フォルダーで自作Viewのレイアウトを作成していきます。
今回使うのはTextViewとButtonです。これらをLinearLayoutで囲んでいきます。

```xml:my_original_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/my_original_view_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/green_message"
        android:textColor="@android:color/black"
        android:layout_marginBottom="20dp"/>

    <Button
        android:id="@+id/my_original_view_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:text="@string/button_text"
        android:textColor="@android:color/white"/>

</LinearLayout>
```

これで手順1は以上です。このxmlが一つのViewとして成り立つことになります。

手順1は普段使っている感じに作っていきました。そこまで特殊ではありませんね。

###手順その2 作成したxmlに機能を加えるJava or Kotlinクラスの作成
ここから普段しないような書き方をしていきます。
手順1を終えた後はJava or Kotlinの新たなクラスを作成していきます。今回はMyOriginalView.ktを作成します。
そして、作成したクラスに先ほど手順1の親ViewのLinearLayoutを継承させます。

```kotlin:MyOriginalView.kt
// 自作Viewクラス
class MyOriginalView(context: Context,
                     attributeSet: AttributeSet): LinearLayout(context, attributeSet) {

}
```

引数の部分ですが、基本的にContextとAttributeSetでなんとかなると思いますが、他のサイトを色々みているとそれ以外のコンストラクタも必要だったりする場合があるそうです。これで動かなかった時は他のサイトに飛んでみてください。

そして初期化時に、手順1のレイアウトファイルを割り当てます。

```kotlin:MyOriginalView.kt
// 自作Viewクラス
class MyOriginalView(context: Context,
                     attributeSet: AttributeSet): LinearLayout(context, attributeSet) {
    init{
        // このクラスに対応するViewを設定する : my_original_view.xml
        LayoutInflater.from(context).inflate(
            R.layout.my_original_view, this, true
        )
    }
}
```

これでMainAcitvityで使えるようになりました。これにTextViewとButtonの挙動を書いていきます。

最終的にこのような感じにしました。

```kotlin:MyOriginalView.kt
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.LinearLayout
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.my_original_view.view.*

// 自作Viewクラス
class MyOriginalView(context: Context,
                     attributeSet: AttributeSet) : LinearLayout(context, attributeSet) {

    private var buttonChecker = false

    init{

        // このクラスに対応するViewを設定する : my_original_view.xml
        LayoutInflater.from(context).inflate(
            R.layout.my_original_view, this, true
        )
        setOnButtonClickListener()
    }

    private fun setOnButtonClickListener(){

        // my_original_view.xml内にあるViewはそのViewのidで取得する
        my_original_view_button.setOnClickListener {
            if(!buttonChecker) {
                it.setBackgroundColor(
                    ContextCompat.getColor(
                        context, R.color.colorAccent
                    )
                )

                // my_original_view.xml内にあるViewはそのViewのidで取得する
                my_original_view_text.text = context.getString(R.string.red_message)
                buttonChecker = true
            }
            else {
                it.setBackgroundColor(
                    ContextCompat.getColor(
                        context, R.color.colorPrimary
                    )
                )

                // my_original_view.xml内にあるViewはそのViewのidで取得する
                my_original_view_text.text = context.getString(R.string.green_message)
                buttonChecker = false
            }
        }
    }

}
```

###手順その3 MainActivityで使用
作ったViewをMainActivityで使用と書いていますが、MainActivityでは書かなくても利用でき、main_activity.xmlに記述するだけで機能します。

```xml:main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.iwacchi.myoriginalview.MyOriginalView
        android:id="@+id/myOriginalView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
```

以上で実行していただけると、貼ったgifのとおりに挙動すると思います。割とすぐに簡単な自作Viewを作ることができるのではないかと思います。

#おわりに
わかりやすくするために簡単な自作Viewを紹介しましたが、これだと自作Viewにするまでもないと思いまして、これを少し応用してアニメーションをつけたいい感じのオリジナルButtonを作成してみました。

![ezgif-5-989fba684c30.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288250/456d9628-7deb-d9ab-da2b-75958f23b4fb.gif)

このコードはGitHubに載せておりますので気になった方はご覧ください。

GitHub → [https://github.com/iwacchi/MyOriginalView](https://github.com/iwacchi/MyOriginalView)