Android app development with Kotlin: Fragment

Kotlin: 1.2.71
Android Studio: 3.2.1

#Fragment
Official: https://developer.android.com/guide/components/fragments
It's a View object (If you are familiar with iOS, you can imagine this as UIViewController

##Create
You can easily add Fragment by clicking the package you want to add, right click
New -> Fragment
<img width="512" alt="AddRoot.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/245077/53bb4dd7-5293-eef3-9de1-6c28d573a8e9.jpeg">
**Fragment (Blank)**: Creates a blank Fragment
**Fragment (List)**: Creates a Fragment with RecyclerView
**Fragment (with ViewModel)**: Creates a Fragment with ViewModel (For MVVM architecture
I don't use other 2 Fragments remaining
##Blank Fragment
<img width="512" alt="BlankFragmentConfigure.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/245077/31e142f9-bf76-254d-ee97-af12b8a1b175.jpeg">
**Fragment Name:** Give Fragment a name
**Create layout XML?**: Keep check it on if you want to make layout. Also set the name of the layout. **If you want to use the existing layout**, then Uncheck this option.
**Include fragment factory methods for easy instantiation:** This makes easier to initialize this Fragment
**Include interface callbacks?**: This makes a custom interface like OnClickListener. If you have a callback already or want to use custom callback, then uncheck this option.

This time, I unchecked Create layout XML and Include interface callbacks. And Android Studio makes BlankFragment like this
![BlankFragment.jpg](https://qiita-image-store.s3.amazonaws.com/0/245077/e3abe789-465b-bea7-258e-cad94f64f09b.jpeg)
##Fragment with List (RecyclerView
https://qiita.com/Galaxy/items/ec49da368d3dc0cc451f
##Fragment with ViewModel (For MVVM
<img width="400" alt="MVVMConfigure.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/245077/9f84fc1c-146b-942e-d955-3150f5e62e58.jpeg">

```kotlin
class MVVMFragment : Fragment() {

    companion object {
        fun newInstance() = MVVMFragment()
    }

    private lateinit var viewModel: MVVMViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.mvvm_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProviders.of(this).get(MVVMViewModel::class.java)
        // TODO: Use the ViewModel
    }

}
```

```kotlin
class MVVMViewModel : ViewModel() {
    // TODO: Implement the ViewModel
}
```
##Initialize Fragment
To initialize a Fragment, simply

```kotlin
val fragment = MVVMFragment.newInstance()
```
**If you want to pass the data to Fragment:**
**Fragment side:** Set arg to newInstance and put it to Bundle and give to argument. **Any** means you can put any type of data, but type have to be supported by Bundle. (Such as Int, String, Serializable

```kotlin
companion object {
    private const val DATA_KEY = "DATA_KEY"

    fun newInstance(data: Any) = MVVMFragment().apply {
        arguments = Bundle().apply {
            putString(DATA_KEY, data as String)
        }
    }
}
```
**Initialize side:**
You can set any type to data, but it have to be supported by Bundle.

```kotlin
val fragment = MVVMFragment.newInstance(data)
```
**Get the data**

```kotlin
val data = arguments?.getString(DATA_KEY)
```
##Add Fragment
Add a Fragment. **Imagine this as appending the Fragment** to **R.id.main_container**. It won't override the layout on **main_container**.
**R.id.main_container** is a layout of **FrameLayout**. **You can only add or replace fragment to FrameLayout**

```kotlin
from Activity
supportFragmentManager.beginTransaction().add(R.id.main_container, fragment).commit()

from Fragment
fragmentManager?.beginTransaction()?.add(R.id.main_container, fragment)?.commit()
```
##Replace Fragment
Replace a Fragment. This **replaces the Fragment** on R.id.main_container.

```kotlin
from Activity
supportFragmentManager.beginTransaction().replace(R.id.main_container, fragment).commit()

from Fragment
fragmentManager?.beginTransaction()?.replace(R.id.main_container, fragment)?.commit()
```

##Remove Fragment

```kotlin
from Activity
supportFragmentManager.beginTransaction().remove(fragment).commit()

from Fragment
fragmentManager?.beginTransaction()?.remove(fragment)?.commit()
```
##LifeCycle
Fragment also has their own LifeCycle. It's similar to Activity's LifeCycle.
###onCreate
Called when Fragment created

###onCreateView()
Called to create View Layout. Specify the layout resource here

###onViewCreated()
Called when View created. Initialize layout components here

```kotlin
(Example)
button.setOnClickListener { }
textView.text = ""
```

See the official site to learn more.
##Enable Menu updates
By setting (I'll prefer to set it to onCreate() or onViewCreated()

```kotlin
setHasOptionsMenu(true)
```
The menu will able to be update when

```kotlin
invalidateOptionsMenu()
``` 
called. You can only call this method from the Activity, or to call it from Fragment

```kotlin
activity?.invalidateOptionsMenu()
```
#Samples
Code: https://github.com/GalaxyDevGamer/Android-Samples/tree/master/app/src/main/java/galaxysoftware/androidsamples/fragment