Wiring Up Assets for Use

Now that you have your asset filenames, you should present them to the user. Eventually, you will want the files to be played, so it makes sense to have an object responsible for keeping track of the filename, the name the user should see, and any other information related to that sound.

Create a Sound class to hold all of this.

Listing 19.14  Creating Sound object (Sound.kt)

private const val WAV = ".wav"

class Sound(val assetPath: String) {

    val name = assetPath.split("/").last().removeSuffix(WAV)
}

In the constructor, you do a little work to make a presentable name for your sound. First, you split off the filename using String.split(String).last(). Once you have done that, you use String.removeSuffix(String) to strip off the file extension, too.

Next, build up a list of Sounds in BeatBox.loadSounds().

Listing 19.15  Creating Sounds (BeatBox.kt)

class BeatBox(private val assets: AssetManager) {

    val sounds: List<Sound>

    init {
      sounds = loadSounds()
    }

    fun loadSounds(): List<String>List<Sound> {

        val soundNames: Array<String>

        try {
            val soundNames = assets.list(SOUNDS_FOLDER)!!
            Log.d(TAG, "Found ${soundNames.size} sounds")
            return soundNames.asList()
        } catch (e: Exception) {
            Log.e(TAG, "Could not list assets", e)
            return emptyList()
        }
        val sounds = mutableListOf<Sound>()
        soundNames.forEach { filename ->
            val assetPath = "$SOUNDS_FOLDER/$filename"
            val sound = Sound(assetPath)
            sounds.add(sound)
        }
        return sounds
    }
}

Now, wire up SoundAdapter to the List of Sounds.

Listing 19.16  Hooking up to the Sound list (MainActivity.kt)

private inner class SoundAdapter(private val sounds: List<Sound>) :
        RecyclerView.Adapter<SoundHolder>() {
    ...

    override fun onBindViewHolder(holder: SoundHolder, position: Int) {
    }

    override fun getItemCount() = 0sounds.size
}

And now pass in BeatBox’s sounds in onCreate(Bundle?).

Listing 19.17  Passing in Sounds to the adapter (MainActivity.kt)

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

    binding.recyclerView.apply {
        layoutManager = GridLayoutManager(context, 3)
        adapter = SoundAdapter(beatBox.sounds)
    }
}

Finally, remove the BeatBox.loadSounds() function call in onCreate.

Listing 19.18  Removing BeatBox.loadSounds() from onCreate(…) (MainActivity.kt)

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    beatBox = BeatBox(assets)
    beatBox.loadSounds()
    ...
}

Since BeatBox.loadSounds() is no longer being called from outside of BeatBox’s initializer block, there is no need to keep this function public. To be a good citizen and avoid inadvertently calling loadSounds() from other parts of the code, update its visibility modifier to private.

Listing 19.19  Updating BeatBox.loadSounds()’s visibility modifier to private (BeatBox.kt)

class BeatBox(private val assets: AssetManager) {
    ...
    private fun loadSounds(): List<Sound> {
        ...
    }
}

With that, you should see a grid of buttons when you run BeatBox (Figure 19.6).

Figure 19.6  Empty buttons

Empty buttons

To populate the buttons with titles, you will use some additional tools from your new data binding utility belt.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.211.66