Android　Viewの表示のさせ方の色々

次の記事を見つけました。こちらを読んだ方がいいかもしれません。＜2020/01/16追記＞
[2019-12-04 Hello ViewBinding! 歴史から学ぶ明日からViewBindingを使うべき理由](https://engineer.retty.me/entry/2019/12/04/120000)

###前書き
　昨今、AndroidStudio"4.1"になって以来、Google帝国の一枚のお触れ書き「[Kotlin Android Extensions の未来](https://developers-jp.googleblog.com/2020/11/the-future-of-kotlin-android-extensions.html)」により、我々一般庶民の初級アンドロイドプログラマーはViewが表示できず、焦り、慄(おのの)いているのではないでしょうか。
　なぜかと言えば、ViewBingdingが登場したからです。
　Viewの表示のさせ方は、私の知る限り、現在４種類あります。（歴史を紐解けば、或るは近い未来を仰ぎ見れば、他にもあるかもしれません。ご存じの方がいれば、ぜひレクチャーしてください。）
　そこで、表示するViewの数が必要最低限にとどまるよう、この４種類のコードの書き方をこのレポートにまとめて記述したいと思います。

　　　（１）レイアウトファイルを使わずコード(Kotlin)だけで動的に書く(動的というほどでもないが、、、）
　　　（２）レイアウトファイルを使って書く
　　　（３）消え去ろうとしているKotlin-Android-Extensionsを使って書く
　　　（４）お触れ書きの主人公、ViewBingdingを使って書く

　Viewの数を必要最低限に留めるため、表示する画面は次のとおりTextView、１つのみをします。
![画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/29946e0f-8a4f-7372-563b-b909c0b35356.png)
　もし記述に間違えがあれば、ご指摘いただければ幸いです。

##0.確認
　AndroidStudio4.1を使って、Kotlinを使ってコードを書く前提で、以下のレポートを作成する。
　まず、新規にプロジェクトを作り、何も手を加えていない状態のbuild.gradele(Module:app)ファイルとMainActivity.ktを示す。以下の作業で作成したファイルと見比べてください。
　build.gradele(Module:app)ファイルには、プラグインが２つ、android{}ブロックの中が6つ、それにdependencies{}ブロックがある。

```build.gradele
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"
    defaultConfig { // 省略 }
    buildTypes { // 省略 }
    compileOptions { // 省略 }
    kotlinOptions { // 省略 }
}
dependencies { // 省略 }
```


MainActivity.ktファイルには、インポートが２つある。

```MainActivity.kt
package com.example.testview03

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)    // 初期設定でactivity_main.xmlファイルを使って画面のレイアウトを表示することを前提にしているため、丸括弧内でR.layout.activity_mainを指定している。
    }
}
```

##1.レイアウトファイルを使わず、コード(Kotlin)だけで動的に書く
　まず、AndroidStudio4.1で、Kotlinを使う前提で、新規にプロジェクトを作る。
　レイアウトは動的に作るため、Activity_main.xmlファイルは不要なので削除する。
　![layoutフォルダ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/2513c0f5-d478-5c13-fd71-6436d0668d00.png)

　次に以下のようにコードを打ち込む。（このコードを書くにあたって、[nyan のアプリ開発](https://akira-watson.com/android/button-hardcoding.html)を参考にした。）
　以下のコードの通り、Activity_main.xmlファイルで担っていたviewのレイアウトは、以下のコードの「レイアウトの設定」と「textViewの設定」の部分で行っている。
　元々、setContentView(R.layout.activity_main)と記述されていた箇所は、丸括弧の中をlayoutと書き換え、コードで書かれたレイアウトの設定が反映されるようになっている。
　またtextViewは、layout.addView(textView)の部分でレイアウトに追加され、画面上に表示される。


```MainActivity.kt
class MainActivity : AppCompatActivity() {

    private lateinit var textView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // レイアウトの設定（リニアレイアウトとする）
        val layout = LinearLayout(this)
        layout.setOrientation(LinearLayout.VERTICAL)    // orientationは垂直方向
        layout.setLayoutParams(        // Layoutの横・縦幅の指定
            LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT
            )
        )

//        setContentView(R.layout.activity_main)    // activity_main.xml ファイルも削除済
        setContentView(layout)      // レイアウトをContentViewに張り付ける

        // textViewの設定
        textView = TextView(this)
        textView.text = "Hello Kotlin Code Only!!"
        textView.textSize = 32.0F // フォントサイズを指定する単位spとの関係は調べていない。Fはfloat型を表す
        textView.setTextColor(Color.rgb(0x0, 0x0, 0x0))     // 文字の色指定（黒）
        textView.setLayoutParams(
            LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
            )
        )

        layout.addView(textView)    // textViewをレイアウトに張り付ける
    }
}
```

　以上を入力し、赤文字の部分をAlt＋Enterで補完入力すると、次の３つのクラスがインポートされる。ここでポイントとなるのが、widgetが付されたクラスである。詳しいことは分からないが、このクラスがあるから、コードだけでレイアウトを作ることができると考えられる。

```MainActivity.kt
import android.graphics.Colorimport 
import android.widget.TextView
import android.widget.LinearLayout
```

　また、以上のコードだけでViewを動的に書くことができるため、build.gradele(Module:)ファイルは、以下のように変更していない。

```build.gradele
plugins {
    id 'com.android.application'
    id 'kotlin-android'
}
 // 以下省略
```

　以上をコンパイルし、実行すれば、エミュレータ上に上部に示した画面が表示されるはずである。


##2.レイアウトファイルを使って書く
　まず、AndroidStudio4.1で、Kotlinを使う前提で、新規にプロジェクトを作る。
　続いて、レイアウトファイルを作成する。新規に作成したレイアウトファイルは、コンストレインレイアウト(ConstraintLayout)の形式で書かれているが、今回は第１項のコードによるViewと同様にリニアレイアウトの形式で作ることに統一した。

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:textSize="36sp" />

</LinearLayout>
```

　次に、MainActivity.ktファイルを書く。setContentView()の行の下にTextViewを表示するためのコードを書く。この行のfindViewById<>()によりtextViewのインスタンスが作られ、また次の行のtextView.textで表示するテキスト文字を設定している。コードによる方法で定義していた文字の大きさや色はレイアウトファイルactivity_main.xmlの android:textColor="@color/black"の行やandroid:textSize="36sp"の行で定義している。

```MainActivity.kt

package com.example.testview01

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView                                  // コード補完により追記

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

        val textView = findViewById<TextView>(R.id.textView)    // 追記 
        textView.text = "Hello findViewById!"                   // 追記
    }
}
```


##3.消え去ろうとしているKotlin-Android-Extensionsを使って書く
　まず、AndroidStudio4.1で、Kotlinを使う前提で、新規にプロジェクトを作る。
　次に、Kotlin-Android-Extensionsの機能を使えるようにするために、build.gradele(Module:app)ファイルに一行追加する。
　この１行を追加することで、AndroidStudio4.0までで書いていたコードをAndroidStudio4.1上で使えるようになる。AndroidStudio4.0までは、プロジェクトを新規で作成した時に、この行がデフォルトで書かれていたそうである。なおKotlin-Android-Extensionsは、「[お触書](https://developers-jp.googleblog.com/2020/11/the-future-of-kotlin-android-extensions.html)」によると、2021 年 9 月またはそれ以降の Kotlin リリースでは削除されるそうだ。

```build.gradele
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-android-extensions'   // 追記
}
```
　build.gradele(Module:app)ファイルを変更したら、左上のSync Nowをクリックする。

![buildGradle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/7ab95a5b-d093-cb61-9ab1-4e8d06b0849a.png)



次にレイアウトファイルを作成する。このファイルは、第２項のactivity_main.xmlとまったく同じである。

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:textSize="36sp" />

</LinearLayout>
```

　次に、MainActivity.ktファイルを作成する。このファイルは、第２項のMainActivity.ktファイルとほぼ同じであるが、差異のある部分はコメント(// 追記)及びコメントアウト(// コード)により表記している。以下のコードを見れば分かるように、第２項の方法でtextViewのインスタンスを作っていたfindViewById<>()の行が削除（コメントアウト）されているが、これはKotlin-Android-Extensionsの機能に因るところで、どこか別のクラス(またはファイル)で定義しているためと考えられる。この付近の事に詳しい方がいれば、ぜひレクチャーして頂きたい。

```MainActivity.kt
package com.example.testview03

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*           // コード補完により、追記
//import android.widget.TextView                                  // 第２項のインポート文をコピペした場合、使用しないので不要

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

//        val textView = findViewById<TextView>(R.id.textView)    //Kotlin-Android-Extensionsの機能により削除
        textView.text = "Hello Kotlin-Android-Extensions!"                   
    }
}
```


##4.お触れ書きの主人公、ViewBingdingを使って書く
　最後に新たな主役、ViewBindingを使って書く。
　まず、AndroidStudio4.1で、Kotlinを使う前提で、新規にプロジェクトを作る。
　次に、ViewBindingの機能を使えるようにするために、build.gradele(Module:app)ファイルのandroid{}ブロックの中に、buildFeatures{}ブロックを追加する。

```build.gradele
plugins { // 省略 }
android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"
    defaultConfig { // 省略 }
    buildTypes { // 省略 }
    compileOptions { // 省略 }
    kotlinOptions { // 省略 }

    buildFeatures {           // 追記
        viewBinding = true    // 追記
    }                         // 追記

}
dependencies { // 省略 }
```

その後、左上にあるSync Nowをクリックする。
![buildGradle設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501068/27071741-5137-7063-45c9-d426f52ad2d8.png)
これで、ViewBindingが使えるようになった。

　次にレイアウトファイルを作る。これも第2項、第３項と同じものである。

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/black"
        android:textSize="36sp" />

</LinearLayout>
```

最後に、MainActivity.ktファイルを作る。

```MainActivity.kt
package com.example.testview04

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.testview04.databinding.ActivityMainBinding   // コード補完により、追記
// import kotlinx.android.synthetic.main.activity_main.*           // 削除

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding   // 追記

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        binding = ActivityMainBinding.inflate(layoutInflater)    // 追記
        
        // setContentView(R.layout.activity_main)    // 削除
        setContentView(binding.root)    // 追記

        // textView.text = "Hello Kotlin-Android-Extensions!"
        binding.textView.text = "Hello BindingView!"
    }
}
```

　なお、ViewBindingについては、「金田著[はじめてのAndroidプログラミング 第５版](https://www.sbcr.jp/product/4815607968/)」を参考にした。またAndroid デベロッパードキュメントガイド [ビュー バインディング](https://developer.android.com/topic/libraries/view-binding)]にも、同様なことが書かれているが、わかりやすさ、例の多さでは「金田著[はじめてのAndroidプログラミング 第５版](https://www.sbcr.jp/product/4815607968/)」には敵わない。

###最後に
　Viewの表示のさせ方４種類を列挙したが、私自身あまり理解をしていないので、解説をつけることはできなかった。コードの書き方の特徴が皆さんに伝わればと思います。
　ViewBindingについては、掌田著「[AndroidJetpackプログラミング](https://www.shuwasystem.co.jp/book/9784798063218.html)」にも記述があるが、[Amazonのレビュー](https://www.amazon.co.jp/Android-Jetpack%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Studio-Kotlin%E5%AF%BE%E5%BF%9C/product-reviews/4798063215/ref=cm_cr_dp_d_show_all_btm?ie=UTF8&reviewerType=all_reviews)にもあるが、内容が著作当時の最先端に近い部分が書かれているためか、理解できず第２章にも届かず本棚に眠っています。改訂版の出版が望まれます。どなたか、この本を解説してくださる方、いらっしゃいませんか？