# 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`