《Android編程權(quán)威指南》之?dāng)?shù)據(jù)綁定與MVVM(二)

《Android編程權(quán)威指南》第 19 章第二篇驾诈,補充完 BeatBox 應(yīng)用啦徽职。

第一篇地址:

https://juejin.cn/post/7032485144078319653

六谅阿、導(dǎo)入 assets

創(chuàng)建 BeatBox 類郑藏,AssetManager 類可以訪問 assets渗柿。

class BeatBox(private val assets: AssetManager) {

    fun loadSounds(): List<String> {
        try {
            val soundNames = assets.list(SOUNDS_FOLDER)!!
            Log.d(TAG, "Found ${soundNames.size} sounds")
            return soundNames.asList()
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e(TAG, "Could not list assets", e)
            return emptyList()
        }
    }
}

AssetManager.list(String) 能列出指定目錄下的所有文件名堵第,傳入聲音資源所在的目錄兆旬,就能看到其中的所有.wav文件假抄。

在 MainActivity 中創(chuàng)建 BeatBox 實例,并調(diào)用 loadSounds() 函數(shù)爵憎。

        beatBox = BeatBox(assets)
        beatBox.loadSounds()

運行結(jié)果如下慨亲,可以看到已經(jīng)讀到 assets 里的文件。

assets

七宝鼓、使用 assets

  • 創(chuàng)建 Sound 管理類刑棵,使用 String.split(String).last() 分離出文件名,再使用 String.removeSuffix(String) 刪除.wav后綴愚铡。
private const val WAV = ".wav"

class Sound(val assetPath: String) {
    val name = assetPath.split("/").last().removeSuffix(WAV)
}
  • 在 BeatBox.loadSounds() 中創(chuàng)建 Sound 對象集合蛉签。
class BeatBox(private val assets: AssetManager) {

    private val sounds: List<Sound>

    init {
        sounds = loadSounds()
    }

    fun loadSounds(): List<Sound> {
        val soundNames: Array<String>

        try {
            soundNames = assets.list(SOUNDS_FOLDER)!!
        } catch (e: Exception) {
            e.printStackTrace()
            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
    }
}
  • 綁定 Sound 對象集合

    private inner class SoundAdapter(private val sounds:List<Sound>):RecyclerView.Adapter<SoundHolder>(){
        ...
        override fun getItemCount() = sounds.size
    }
  • 傳入聲音資源(MainActivity.kt)
 adapter = SoundAdapter(beatBox.sounds)

運行結(jié)果:

使用assets

八、綁定數(shù)據(jù)

  • 創(chuàng)建 SoundViewModel 類并添加綁定函數(shù)沥寥。
class SoundViewModel {

    var sound: Sound? = null
        set(sound) {
            field = sound
        }

    val title: String?
        get() = sound?.name
}
  • 綁定至視圖模型
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel"
            type="com.pyn.beatbox.SoundViewModel" />
    </data>

    <Button
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:text="@{viewModel.title}"
        tools:text="Sound name" />

</layout>
  • 關(guān)聯(lián)使用視圖模型
    private inner class SoundHolder(private val binding:ListItemSoundBinding):RecyclerView.ViewHolder(binding.root){

        init {
            binding.viewModel = SoundViewModel()
        }
        
        fun bind(sound:Sound){
            binding.apply {
                viewModel?.sound = sound
                executePendingBindings()
            }
        }
    }
...
        override fun onBindViewHolder(holder: SoundHolder, position: Int) {
            val sound = sounds[position]
            holder.bind(sound)
        }
  • 綁定數(shù)據(jù)觀察
class SoundViewModel : BaseObservable() {

    var sound: Sound? = null
        set(sound) {
            field = sound
            notifyChange()
        }

    @get:Bindable
    val title: String?
        get() = sound?.name
}

調(diào)用 notifyChange()碍舍,就是通知綁定類,視圖模型對象上所有可綁定屬性都已更新邑雅。

運行結(jié)果:

demo

九片橡、深入學(xué)習(xí):數(shù)據(jù)綁定再探

有關(guān)數(shù)據(jù)綁定(DataBinding)庫更加深入的介紹請參考:

https://developer.android.com/topic/libraries/data-binding

lambda 表達式「布局里面也可以使用 lambda 表達式寫短回調(diào)」

比如給 item 中的 button 添加點擊時間可以寫成:

 android:onClick="@{() -> viewModel.onButtonClick()}"

數(shù)據(jù)綁定還有一些方便的語法可用。最方便的一個是使用單引號代替雙引號淮野,它還有 null 自動處理機制捧书。

數(shù)據(jù)綁定默認(rèn)會把綁定表達式解讀為屬性函數(shù)調(diào)用。

比如要定義一個 app:isGone 屬性骤星,基于某個布爾值來設(shè)置所有 View 的可見性经瓷,可以這么做:

@BindingAdapter("app:isGone")
fun bindIsGone(view: View, isGone: Boolean) {
    view.visibility = if (isGone) View.GONE else View.VISIBLE
}

TextViewBindingAdapter 就為 TextView 提供了一些特別的屬性操作。你可以在Android Studio 里看看它們的源碼洞难。當(dāng)然也有搜到 AutoCompleteTextViewBindingAdapter舆吮、CheckedTextViewBindingAdapter 這些類,可自行查查看看队贱。

十色冀、深入學(xué)習(xí):LiveData和數(shù)據(jù)綁定

class SoundViewModel{

    val title :MutableLiveData<String?> = MutableLiveData()

    var sound: Sound? = null
        set(sound) {
            field = sound
            title.postValue(sound?.name)
        }
}
 private inner class SoundAdapter(private val sounds:List<Sound>):RecyclerView.Adapter<SoundHolder>(){

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
            SoundHolder{
                ...
                binding.lifecycleOwner = this@MainActivity
                return SoundHolder(binding)
        }
        ...
    }

其他

BeatBox 項目 Demo 地址:

https://github.com/visiongem/AndroidGuideApp/tree/master/BeatBox

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市柱嫌,隨后出現(xiàn)的幾起案子呐伞,更是在濱河造成了極大的恐慌,老刑警劉巖慎式,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡瘪吏,警方通過查閱死者的電腦和手機癣防,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掌眠,“玉大人蕾盯,你說我怎么就攤上這事±侗” “怎么了级遭?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長渺尘。 經(jīng)常有香客問我挫鸽,道長,這世上最難降的妖魔是什么鸥跟? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任丢郊,我火速辦了婚禮,結(jié)果婚禮上医咨,老公的妹妹穿的比我還像新娘枫匾。我一直安慰自己,他們只是感情好拟淮,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布干茉。 她就那樣靜靜地躺著,像睡著了一般很泊。 火紅的嫁衣襯著肌膚如雪角虫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天撑蚌,我揣著相機與錄音上遥,去河邊找鬼。 笑死争涌,一個胖子當(dāng)著我的面吹牛粉楚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亮垫,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼模软,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了饮潦?” 一聲冷哼從身側(cè)響起燃异,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎继蜡,沒想到半個月后回俐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逛腿,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年仅颇,在試婚紗的時候發(fā)現(xiàn)自己被綠了单默。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡忘瓦,死狀恐怖搁廓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耕皮,我是刑警寧澤境蜕,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站凌停,受9級特大地震影響粱年,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苦锨,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一逼泣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧舟舒,春花似錦拉庶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至夺鲜,卻和暖如春皆尔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背币励。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工慷蠕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人食呻。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓流炕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親仅胞。 傳聞我的和親對象是個殘疾皇子每辟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容