title: Saving and Restoring ListView (livedata) in Fragments
body: <p>I'm trying to make a Todo app. I have succesfully implemented livedata and listview in fragments (fragments are default from the project quickstart template). My problem which I can't resolve is saving those todo's so they are still there upon launching app back again.</p>
  
  <p>Browsed tons of answers on stack and blogs and read about whole lifecycle but I still don't get it. I finally gave up and this is what (not working) code I end up with atm:</p>
  
  <p><strong>FragmentLifeCycle</strong> to save "<strong>state</strong>" of the <strong>listOfToDoThings</strong></p>
  
  <pre><code>class FragmentLifeCycle : Fragment() {
  
      private var state: Parcelable? = null
  
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          Log.d("Lifecycle Info", "onCreate()")
  
      }
  
      override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
          Log.d("Lifecycle Info", "onCreateView()")
          return inflater.inflate(R.layout.activity_main, container, false)
      }
  
      override fun onActivityCreated(savedInstanceState: Bundle?) {
          super.onActivityCreated(savedInstanceState)
          Log.d("Lifecycle Info", "onActivityCreated()")
  
      }
  
      override fun onResume() {
          super.onResume()
  
          if (state != null) {
              Log.i("Lifecycle Info", "onResume finally works")
              listOfToDoThings.onRestoreInstanceState(state)
          }
  
          Log.d("Lifecycle Info", "onResume()")
  
      }
  
      override fun onPause() {
          state = listOfToDoThings.onSaveInstanceState()
          super.onPause()
          Log.d("Lifecycle Info", "onStop()")
      }
  
  }
  </code></pre>
  
  <p>which throws nullpointer:</p>
  
  <p>'android.os.Parcelable android.widget.ListView.onSaveInstanceState()' on a null object reference</p>
  
  <p>And Main_Activity cleared out of tons of commented not-working solutions:</p>
  
  <pre><code>class MainActivity : AppCompatActivity(){
  
      private var mSectionsPagerAdapter: SectionsPagerAdapter? = null
  
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
  
          setSupportActionBar(toolbar)
          // Create the adapter that will return a fragment for each of the three
          // primary sections of the activity.
          mSectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager)
  
          // Set up the ViewPager with the sections adapter.
          container.adapter = mSectionsPagerAdapter
  
          val fragmentManager = this.supportFragmentManager
          val fragmentTransaction = fragmentManager.beginTransaction()
  
          val fragmentLifeCycle = FragmentLifeCycle()
          fragmentTransaction.add(R.id.container, fragmentLifeCycle, "Lifecycle Fragment")
          fragmentTransaction.commit()
  
      }
  
      override fun onCreateOptionsMenu(menu: Menu): Boolean {
          // Inflate the menu; this adds items to the action bar if it is present.
          menuInflater.inflate(R.menu.menu_main, menu)
  
  
          return true
      }
  
      override fun onOptionsItemSelected(item: MenuItem): Boolean {
          // Handle action bar item clicks here. The action bar will
          // automatically handle clicks on the Home/Up button, so long
          // as you specify a parent activity in AndroidManifest.xml.
          val id = item.itemId
  
          if (id == R.id.action_settings) {
              return true
          }
  
          return super.onOptionsItemSelected(item)
      }
  
      /**
       * A [FragmentPagerAdapter] that returns a fragment corresponding to
       * one of the sections/tabs/pages.
       */
      inner class SectionsPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
  
          override fun getItem(position: Int): Fragment {
              // getItem is called to instantiate the fragment for the given page.
              // Return a PlaceholderFragment (defined as a static inner class below).
              return PlaceholderFragment.newInstance(position + 1)
          }
  
          override fun getCount(): Int {
              // Show 3 total pages.
              return 4
          }
      }
  
  
       /**
       * A placeholder fragment containing a simple view.
       */
      class PlaceholderFragment : Fragment(), Renderer&lt;TodoModel&gt; {
  
          private lateinit var store: TodoStore
  
          override fun render(model: LiveData&lt;TodoModel&gt;) {
              model.observe(this, Observer { newState -&gt;
                  listOfToDoThings.adapter = TodoAdapter(requireContext(), newState?.todos ?: listOf())
              })
          }
  
  
  
          private fun openDialog() {
              val options = resources.getStringArray(R.array.filter_options).asList()
              requireContext().selector(getString(R.string.filter_title), options) { _, i -&gt;
                  val visible = when (i) {
                      1 -&gt; Visibility.Active()
                      2 -&gt; Visibility.Completed()
                      else -&gt; Visibility.All()
                  }
                  store.dispatch(SetVisibility(visible))
              }
          }
  
          private val mapStateToProps = Function&lt;TodoModel, TodoModel&gt; {
              val keep: (Todo) -&gt; Boolean = when(it.visibility) {
  
                  is Visibility.All -&gt; {_ -&gt; true}
                  is Visibility.Active -&gt; {t: Todo -&gt; !t.status}
                  is Visibility.Completed -&gt; {t: Todo -&gt; t.status}
              }
  
              return@Function it.copy(todos = it.todos.filter { keep(it) })
          }
  
          override fun onCreateView(
              inflater: LayoutInflater, container: ViewGroup?,
              savedInstanceState: Bundle?
          ): View? {
  
              val rootView = inflater.inflate(R.layout.fragment_main, container, false)
              rootView.section_label.text = getString(R.string.section_format, arguments?.getInt(ARG_SECTION_NUMBER))
  
              @SuppressLint("SetTextI18n")
              when(arguments?.getInt(ARG_SECTION_NUMBER)) {
                  1 -&gt; rootView.section_name.text = "Daily Life"
                  2 -&gt; rootView.section_name.text = "Work and College"
                  3 -&gt; rootView.section_name.text = "Visits"
                  4 -&gt; rootView.section_name.text = "Shop"
              }
  
              store = ViewModelProviders.of(this).get(TodoStore::class.java)
              store.subscribe(this, mapStateToProps)
  
              // Add task and then reset editText component
              rootView.addNewToDo.setOnClickListener {
                  store.dispatch(AddTodo(editText.text.toString()))
                  editText.text = null
              }
  
              rootView.filter.setOnClickListener{ openDialog() }
  
              // Press to change status of task
              rootView.listOfToDoThings.adapter = TodoAdapter(requireContext(), listOf())
              rootView.listOfToDoThings.setOnItemClickListener { _, _, _, id -&gt;
                  store.dispatch(ToggleTodo(id))
              }
  
              // Hold to delete task
              rootView.listOfToDoThings.setOnItemLongClickListener { _, _, _, id -&gt;
                  store.dispatch(RemoveTodo(id))
                  true
              }
  
              return rootView
          }
  
  
  
          companion object {
              /**
               * The fragment argument representing the section number for this
               * fragment.
               */
              private val ARG_SECTION_NUMBER = "section_number"
  
              /**
               * Returns a new instance of this fragment for the given section
               * number.
               */
              fun newInstance(sectionNumber: Int): PlaceholderFragment {
                  val fragment = PlaceholderFragment()
                  val args = Bundle()
                  args.putInt(ARG_SECTION_NUMBER, sectionNumber)
                  fragment.arguments = args
                  return fragment
              }
          }
      }
  }
  </code></pre>
  
  <p>Not sure if its usefull but that's how TodoStore.kt looks like:</p>
  
  <pre><code>class TodoStore : Store&lt;TodoModel&gt;, ViewModel(){
  
      private val state: MutableLiveData&lt;TodoModel&gt; = MutableLiveData()
  
      // Start with all tasks visible regardless of previous state
      private val initState = TodoModel(listOf(), Visibility.All())
  
      override fun dispatch(action: Action) {
          state.value = reduce(state.value, action)
      }
  
  
      private fun reduce(state: TodoModel?, action: Action): TodoModel {
          val newState= state ?: initState
  
          return when(action){
  
              // Adds stuff upon creating new todo
              is AddTodo -&gt; newState.copy(
                  todos = newState.todos.toMutableList().apply {
                      add(Todo(action.text, action.id))
                  }
              )
  
              is ToggleTodo -&gt; newState.copy(
                  todos = newState.todos.map {
                      if (it.id == action.id) {
                          it.copy(status = !it.status)
                      } else it
                  } as MutableList&lt;Todo&gt;
              )
  
              is SetVisibility -&gt; newState.copy(
                  visibility = action.visibility
              )
  
              is RemoveTodo -&gt; newState.copy(
                  todos = newState.todos.filter {
                      it.id != action.id
                  } as MutableList&lt;Todo&gt;
              )
          }
      }
  
      override fun subscribe(renderer: Renderer&lt;TodoModel&gt;, func: Function&lt;TodoModel, TodoModel&gt;) {
          renderer.render(Transformations.map(state, func))
      }
  
  }
  </code></pre>