AndroidStudio(kotlin)でListViewを使ったButton、ImageViewの表示

今回はBaseAdadpterクラスをCustomAdapterに継承しました。
初心者なので非効率なところばかりだと思います。
kotlinで書いているサイトが少なかったのでJavaのコードも結構参考にしました。
##参考サイト
[ListViewの中にあるボタンからリスナーを取得したい: Javaコード](https://qiita.com/meru_h/items/f4006016733968e398af)
この記事はJavaでコードを書いていますがとても参考になりました。
Javaで開発するなら一番わかりやすいと思います。
[ListViewの項目にボタン付きの自作レイアウトを設定: Kotlinコード](https://joyplot.com/documents/2018/01/18/kotlin-listview-button/)
このサイトはBaseAdapterを使ってはいないもののわかりやすかったです。Dataクラスを使うところとかめちゃくちゃ参考にしました。

##機能
ListViewでButtonとImageViewの表示
Buttonを押すとそのボタンに対応した画像表示と音声再生


##コード
BaseAdapterを継承したCustomAdapterクラスです。
fadeout機能はおまけみたいなもので、イメージがボタンを押すと引数の時間だけ画像が表示されて消えていきます。
CustomAdapterのyzはMainActivityで宣言してます。


```kotlin:CustomAdapter.kt
package work.prgrm.yz

import android.content.Context
import android.media.SoundPool
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AlphaAnimation
import android.widget.*
import android.widget.BaseAdapter


class CustomAdapter(
    private val context: Context,
    private var inflater: LayoutInflater,
    private var layoutId: Int,

    private val soundPool:SoundPool,
    private var yz: List<MainActivity.Buttons>
                    ) : BaseAdapter()  {
    internal data class ViewHolder(val button:Button,val image:ImageView)

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        var view = convertView
        val viewHolder : ViewHolder
        if (convertView == null) {
            view = inflater.inflate(layoutId,parent,false)
            viewHolder = ViewHolder(view.findViewById(R.id.button),view.findViewById(R.id.imageView))
            view.tag = viewHolder
        } else {
            viewHolder = view!!.tag as ViewHolder
        }
        viewHolder.button.setText(yz[position].button)
        val soundId = soundPool.load(context, yz[position].sound, 1)
        viewHolder.image.setImageResource(yz[position].image)
        fadeout(viewHolder.image,0)
        viewHolder.button.setOnClickListener() {
            soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f)

            fadeout(viewHolder.image,3000)
        }
        return view!!
    }

    override fun getCount(): Int {
        return yz.size
    }

    override fun getItem(position: Int): Any {
        return position
    }

    override fun getItemId(position: Int):Long {
        return position.toLong()
    }

}
private fun fadeout(imageView:ImageView,Duration:Long){
    val alphaFadeOut = AlphaAnimation(1.0f,0.0f)
    alphaFadeOut.setDuration(Duration)
    alphaFadeOut.setFillAfter(true)
    imageView.startAnimation(alphaFadeOut)
}
```
row.xmlはListViewに入れるレイアウトです。

```xml:row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginStart="30dp"
        android:layout_toEndOf="@+id/button"/>

</RelativeLayout>
```
yzのリストの中にあるButtonsの数だけButtonとImageViewがMainActivityに表示されます。
Buttonsのbuttonでボタンに表示されるフレーズをきめて、soundで再生される音声を決めて、imageでImageViewに表示される画像を決めます。
画像はresの下のdrawableフォルダに、音声はresの下のrawフォルダに入れてます。

```kotlin:MainActivity.kt
package work.prgrm.yz

import android.content.Intent
import android.media.SoundPool
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.*
import kotlinx.android.synthetic.main.activity_main.*
import android.widget.AdapterView





class MainActivity : AppCompatActivity() {
    data class Buttons(val button: String,val sound: Int,val image: Int)
    private val soundPool = SoundPool.Builder().setMaxStreams(2).build()
    private val yz = listOf(
        Buttons("こ↑こ↓",R.raw.koko,R.drawable.koko),
        Buttons("多少はね",R.raw.tashouhane,R.drawable.koko)
        //Buttons(R.id.button3,R.raw.tashouhane,R.drawable.yarimasune),
        //Buttons(R.id.button4,R.raw.yarimasune,R.drawable.yarimasune)
    )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val listView = findViewById<ListView>(R.id.ListView)
        val adapter = CustomAdapter(this,LayoutInflater.from(applicationContext), R.layout.row,soundPool,yz)
        listView.setAdapter(adapter)
    }
}
```

button6は気にしないでください

``` xml:activity_main.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">

    <Button
        android:id="@+id/button6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <ListView
        android:id="@+id/ListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toTopOf="@+id/button6"
        tools:layout_editor_absoluteX="36dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
```

以上です。
これだけでも自分で好きに素材を入れてアプリで再生できるので楽しいですよね。

##困っていること
自分は実機でアプリを動かしていますがこのアプリだけなぜか実機のアプリ一覧に出てきません。
インストール自体はされるんですがいちいちパソコンからRunしないと動いてくれません。
Manifestなど調べましたが全然解決できなかったです。
だれかわかる方いたら教えてほしいです。
あとへんなところとかあったら教えてほしいです。

##ひとこと
この記事がだれかの助けになったらうれしいです。
ちなyzは野獣