title: MVVM Recyclerview Livedata Room SearchView
body: <p>I am making <em>database</em> app using <code>room, mvvm, livedata</code> . I have Prepopulated it with some data. Now i have two options either i am going to show that prepoulated data when app turns on via <code>recyclerview</code>  or show it when i search it using <code>SearchView</code> inside recyclerView.<br/>
  The <strong>Problem</strong> is when i search for particular item, itw shows that item when i complete my word and when i try to go back either my resView back empty or it always stays on that item. i wanna try sometime <em>realtime</em> like: when i enter only one alphabet it show all the suggestions belongs to alphabet, i only want to update with <code>livedata</code><br/>
  What i have try?<br/>
  1->  I have already tried <code>switchMap</code> which worked with <code>liveData</code> but i have to refresh my activity in order to get back my list.<br/>
  2-> I have tried resView filter which didn't worked because i am using livedata to update my UI and also give it regular try without <code>livedata</code> it still didn't work either.<br/>
  3-> I Have tried regular <code>editText</code> just to try but i didn't find it useful as facing same problem, my main focus was on <code>searchView</code>  <br/>
  <strong>RecyclerView code</strong> <em>with filterable or just ignore filterable part it wasn't good try at all</em></p>
  
  <pre><code>class MyAdapter(
      private var context: Context,
      private var dataList: List&lt;SearchPojo&gt;
  ) : RecyclerView.Adapter&lt;MyAdapter.BaseViewHolder&lt;*&gt;&gt;(), Filterable {
  
      private var exampleListFull: List&lt;SearchPojo&gt;? = null
  
      init {
          exampleListFull = ArrayList(dataList)
  
      }
  
      companion object {
          const val SEARCH_TYPE = 1
      }
  
      abstract class BaseViewHolder&lt;T&gt;(view: View) : RecyclerView.ViewHolder(view) {
          abstract fun bind(t: T)
      }
  
      inner class SearchViewHolder(view: View) : BaseViewHolder&lt;SearchPojo&gt;(view) {
          private val userID: TextView = view.findViewById(R.id.idSearch)
          private val userName: TextView = view.findViewById(R.id.nameSearch)
          private val userPos: TextView = view.findViewById(R.id.positionSearch)
  
          override fun bind(t: SearchPojo) {
              userID.text = t.id
              userName.text = t.userName
              userPos.text = t.position
          }
      }
  
  
      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder&lt;*&gt; {
          return when (viewType) {
              SEARCH_TYPE -&gt; {
                  val view =
                      LayoutInflater.from(context).inflate(R.layout.layout_show_data, parent, false)
                  SearchViewHolder(view)
              }
              else -&gt; {
                  throw IllegalAccessException("In valid View Type")
              }
          }
      }
  
      override fun getItemCount(): Int {
          return dataList.size
      }
  
      override fun onBindViewHolder(holder: BaseViewHolder&lt;*&gt;, position: Int) {
          val element = dataList[position]
          when (holder) {
              is SearchViewHolder -&gt; {
                  holder.bind(element)
              }
          }
      }
  
      override fun getItemViewType(position: Int): Int {
          return when (dataList[position]) {
              is SearchPojo -&gt; SEARCH_TYPE
  
              else -&gt; throw IllegalAccessException()
          }
      }
  
      override fun getFilter(): Filter {
          return exampleFilter
      }
  
      private var exampleFilter = object : Filter() {
  
          override fun performFiltering(constraint: CharSequence?): FilterResults {
              val filteredList = ArrayList&lt;SearchPojo&gt;()
  
              if (constraint == null || constraint.isEmpty()) {
                  filteredList.addAll(exampleListFull as Iterable&lt;SearchPojo&gt;)
              } else {
                  val filterPattern = constraint.toString().toLowerCase().trim { it &lt;= ' ' }
  
                  for (item in exampleListFull!!) {
                      if (item.userName.toLowerCase().contains(filterPattern)) {
                          filteredList.add(item)
                      }
                  }
              }
  
              val results = FilterResults()
              results.values = filteredList
  
              return results
          }
  
          override fun publishResults(constraint: CharSequence, results: FilterResults) {
              dataList.clear()
              dataList.addAll(results.values as List&lt;SearchPojo&gt;)
              notifyDataSetChanged()
          }
      }
  
  }
  </code></pre>
  
  <p><strong>Main Activity</strong></p>
  
  <pre><code>class MainActivity : AppCompatActivity() {
  
      lateinit var searchViewModel: SearchViewModel
      lateinit var myAdapter: MyAdapter
  
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
  
          if (!::searchViewModel.isInitialized) {
              searchViewModel = ViewModelProviders.of(this)[SearchViewModel::class.java]
              searchViewModel.getAll().observe(this, Observer {
                  myAdapter(it)
              })
  
          }
  
          searchItems.addTextChangedListener(object : TextWatcher {
              override fun afterTextChanged(s: Editable?) {
              }
  
              override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
              }
  
              override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                  nameFromDb(s.toString())
              }
          })
      }
  
      override fun onCreateOptionsMenu(menu: Menu?): Boolean {
          menuInflater.inflate(R.menu.search_item, menu)
  
          val searchItem = menu!!.findItem(R.id.search_menu)
          val searchView = searchItem.actionView as SearchView
  
  
          searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
              override fun onQueryTextSubmit(query: String?): Boolean {
                  return false
              }
  
              override fun onQueryTextChange(newText: String?): Boolean {
                  myAdapter.getFilter().filter(newText)
                  return true
              }
          })
  
  
          return super.onCreateOptionsMenu(menu)
      }
  
      override fun onOptionsItemSelected(item: MenuItem?): Boolean {
          when (item!!.itemId) {
              R.id.refresh -&gt; {
                  val intent = Intent(this, MainActivity::class.java)
                  startActivity(intent)
              }
          }
          return true
      }
  
  
      private fun nameFromDb(searchTxt: String) {
          searchViewModel = ViewModelProviders.of(this)[SearchViewModel::class.java]
          searchViewModel.items.observe(this, object : Observer&lt;List&lt;SearchPojo&gt;&gt; {
              override fun onChanged(t: List&lt;SearchPojo&gt;?) {
                  if (t == null) {
                      return
                  }
                  myAdapter(t)
              }
          })
  
          searchViewModel.searchIt(searchTxt)
  
      }
  
      private fun myAdapter(t: List&lt;SearchPojo&gt;) {
          searchResultResView.apply {
              layoutManager = LinearLayoutManager(context)
              myAdapter = MyAdapter(this@MainActivity, t)
              adapter = myAdapter
  
          }
      }
  }
  </code></pre>
  
  <p><strong>ViewModel</strong></p>
  
  <pre><code>lass SearchViewModel(application: Application) :
      AndroidViewModel(application) {
      private val repo: SearchRepo = SearchRepo(application)
  
      private val _searchItem : MutableLiveData&lt;String&gt; = MutableLiveData()
  
      val items : LiveData&lt;List&lt;SearchPojo&gt;&gt; = Transformations.switchMap(_searchItem) { myItems -&gt;
          repo.searchItem(myItems)
      }
  
      init {
              _searchItem.value = ""
      }
  
      fun searchIt(items: String) {
          _searchItem.value = items
      }
  
      fun getAll() = repo.allSearch()
  }
  </code></pre>
  
  <p><strong>Repository</strong></p>
  
  <pre><code>class SearchRepo(application: Application) {
  
      private val searchDao: SearchDao
  
  
      init {
          val db = SearchDb.instance(application)
          searchDao = db.searchDao()
  
      }
  
  
      fun searchItem(id: String): LiveData&lt;List&lt;SearchPojo&gt;&gt; {
          return searchDao.searchViaID(id)
      }
  
      fun allSearch() : LiveData&lt;List&lt;SearchPojo&gt;&gt; {
          return searchDao.allSearch()
      }
  
  
  }
  </code></pre>
  
  <p><strong>Dao</strong></p>
  
  <pre><code>@Dao
  abstract class SearchDao : BaseDao&lt;SearchPojo&gt; {
  
      @Query("Select * from SearchPojo")
      abstract fun allSearch(): LiveData&lt;List&lt;SearchPojo&gt;&gt;
  
      @Query("Select * from SearchPojo where userName Like :userNameSearch or LOWER(userName) like LOWER(:userNameSearch)")
      abstract fun searchViaID(userNameSearch: String) : LiveData&lt;List&lt;SearchPojo&gt;&gt;
  
      @Insert
      abstract override fun insert(searchPojo: SearchPojo)
  
  }
  </code></pre>