---
# System prepended metadata

title: ViewModel
tags: [ViewModel, Android, kotlin]

---

# ViewModel

## 使用viewModel來儲存要顯示於UI的資料，在旋轉銀幕後，資料會透過viewModel保存，不會因Activity destory而消失

1.  ### 第一步 : 建立新專案
    #### 在這邊我使用內建的 Fragment + ViewModel樣板，
    #### 建立後，檔案架構如圖2

![圖1](https://i.imgur.com/KSUfT7X.png)
![圖2](https://i.imgur.com/c0vO93e.png)

2. ### 第二步 : 啟用Data Binding (可省略)
    [參考我的筆記][https://hackmd.io/HV-lkNHkQUO4UiV49Mz4Sw]

3. ### 第三步 : 觀察MainActivity.kt 
   #### 在app一開始執行就把main_Activity.xml 頁面更換為main_Fragment.xml
   #### 所以直接在MainFragment.kt與頁面更換為main_Fragment.xml進行修改就好
``` kotlin=0
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                    .replace(R.id.container, MainFragment.newInstance())
                    .commit()
        }
    }
}
```
4. ### 第四步 : 在main_Fragment.xml新增元件，按鈕與TextView
   #### 預計是做一個按鈕，每點一下textView 數值+1 

![圖3](https://i.imgur.com/lq33OSh.png)

5. ### 第五步 : 修改MainFragment.kt
   #### 取得data binding的view 
   #### 覆寫onViewCreated，透過ViewModelProvider取得ViewModel
   #### 註冊按鈕的Listener執行onSkip函數與updateData函數
   #### 注意到onSkip函數實際執行+1的功能與updateData資料是在MainViewModel.kt
   #### 有關要顯示於UI的資料必須存放於ViewModel
   
   ##### MainFragment.kt
```kotlin=0 
class MainFragment : Fragment() {

    companion object {
        fun newInstance() = MainFragment()
    }
    private lateinit var binding : MainFragmentBinding
    private lateinit var viewModel: MainViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        binding =DataBindingUtil.inflate(
                inflater,
                R.layout.main_fragment,
                container,
                false
        )
        return binding.root
//        return inflater.inflate(R.layout.main_fragment, container, false)

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.i("onViewCreated", "view created")

        viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        // TODO: Use the ViewModel
        binding.gen.setOnClickListener { onSkip() }
        updateData()
    }
    // onActivityCreated 與 onViewCreated 功能一樣，後續建議都使用onViewCreated
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        Log.i("onActivityCreated", "onActivityCreated")

    }

    fun onSkip(){
        viewModel.onskip()
        updateData()
    }

    fun updateData(){
        binding.keepsave.text = viewModel.count.toString()
    }

}
```
   #### MainViewModel.kt
```kotlin=0
class MainViewModel : ViewModel() {
    // TODO: Implement the ViewModel
    var count = 0

    fun onskip(){
        count++
    }

    override fun onCleared() {
        super.onCleared()
    }
}
```
## 以上是ViewModel簡單的小範例

[參考資料] : [code lab](https://developer.android.com/codelabs/kotlin-android-training-view-model?index=..%2F..android-kotlin-fundamentals#0 "code lab")
###### tags: `kotlin` `Android` `ViewModel`