Add search functionality

This commit is contained in:
2019-09-23 17:33:02 +02:00
committed by Matte23
parent 8b7f1fcaa4
commit 54aca078d8
11 changed files with 98 additions and 10 deletions

View File

@@ -29,6 +29,7 @@ import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController import androidx.navigation.ui.setupActionBarWithNavController
@@ -46,6 +47,7 @@ class MainActivity : AppCompatActivity(), CircularLetterAdapter.AdapterCallback
internal const val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 10 internal const val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 10
} }
var searchCallback: SearchCallback? = null
override var circularToDownload: Circular? = null override var circularToDownload: Circular? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -80,6 +82,21 @@ class MainActivity : AppCompatActivity(), CircularLetterAdapter.AdapterCallback
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu) menuInflater.inflate(R.menu.menu_main, menu)
(menu.findItem(R.id.menu_main_search).actionView as SearchView).setOnQueryTextListener(
object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
searchCallback?.search(query)
return false
}
override fun onQueryTextChange(query: String): Boolean {
searchCallback?.search(query)
return false
}
})
return true return true
} }
@@ -151,4 +168,8 @@ class MainActivity : AppCompatActivity(), CircularLetterAdapter.AdapterCallback
builder.create().show() builder.create().show()
} }
interface SearchCallback {
fun search(query: String)
}
} }

View File

@@ -29,15 +29,24 @@ interface CircularDao {
@Query("SELECT * FROM circulars ORDER BY id DESC") @Query("SELECT * FROM circulars ORDER BY id DESC")
fun getLiveCirculars(): LiveData<List<Circular>> fun getLiveCirculars(): LiveData<List<Circular>>
@Query("SELECT * FROM circulars WHERE name LIKE :query ORDER BY id DESC")
fun searchCirculars(query: String): LiveData<List<Circular>>
@Query("SELECT * FROM circulars WHERE id = :id ORDER BY id DESC") @Query("SELECT * FROM circulars WHERE id = :id ORDER BY id DESC")
fun getCircular(id: Long): Circular fun getCircular(id: Long): Circular
@Query("SELECT * FROM circulars WHERE favourite ORDER BY id DESC") @Query("SELECT * FROM circulars WHERE favourite ORDER BY id DESC")
fun getFavourites(): LiveData<List<Circular>> fun getFavourites(): LiveData<List<Circular>>
@Query("SELECT * FROM circulars WHERE favourite AND name LIKE :query ORDER BY id DESC")
fun searchFavourites(query: String): LiveData<List<Circular>>
@Query("SELECT * FROM circulars WHERE reminder ORDER BY id DESC") @Query("SELECT * FROM circulars WHERE reminder ORDER BY id DESC")
fun getReminders(): LiveData<List<Circular>> fun getReminders(): LiveData<List<Circular>>
@Query("SELECT * FROM circulars WHERE reminder AND name LIKE :query ORDER BY id DESC")
fun searchReminders(query: String): LiveData<List<Circular>>
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(circulars: List<Circular>) fun insertAll(circulars: List<Circular>)

View File

@@ -34,7 +34,7 @@ import net.underdesk.circolapp.R
import net.underdesk.circolapp.adapters.CircularLetterAdapter import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.viewmodels.CircularLetterViewModel import net.underdesk.circolapp.viewmodels.CircularLetterViewModel
class CircularLetterFragment : Fragment() { class CircularLetterFragment : Fragment(), MainActivity.SearchCallback {
private lateinit var circularLetterViewModel: CircularLetterViewModel private lateinit var circularLetterViewModel: CircularLetterViewModel
@@ -67,6 +67,12 @@ class CircularLetterFragment : Fragment() {
circularLetterViewModel.showMessage.postValue(false) circularLetterViewModel.showMessage.postValue(false)
} }
}) })
(activity as MainActivity).searchCallback = this
return root return root
} }
override fun search(query: String) {
circularLetterViewModel.query.postValue(query)
}
} }

View File

@@ -32,7 +32,7 @@ import net.underdesk.circolapp.R
import net.underdesk.circolapp.adapters.CircularLetterAdapter import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.viewmodels.FavouritesViewModel import net.underdesk.circolapp.viewmodels.FavouritesViewModel
class FavouritesFragment : Fragment() { class FavouritesFragment : Fragment(), MainActivity.SearchCallback {
private lateinit var favouritesViewModel: FavouritesViewModel private lateinit var favouritesViewModel: FavouritesViewModel
@@ -54,6 +54,12 @@ class FavouritesFragment : Fragment() {
(root.circulars_list.adapter as CircularLetterAdapter).changeDataSet(it) (root.circulars_list.adapter as CircularLetterAdapter).changeDataSet(it)
} }
}) })
(activity as MainActivity).searchCallback = this
return root return root
} }
override fun search(query: String) {
favouritesViewModel.query.postValue(query)
}
} }

View File

@@ -32,7 +32,7 @@ import net.underdesk.circolapp.R
import net.underdesk.circolapp.adapters.CircularLetterAdapter import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.viewmodels.RemindersViewModel import net.underdesk.circolapp.viewmodels.RemindersViewModel
class RemindersFragment : Fragment() { class RemindersFragment : Fragment(), MainActivity.SearchCallback {
private lateinit var remindersViewModel: RemindersViewModel private lateinit var remindersViewModel: RemindersViewModel
@@ -54,6 +54,12 @@ class RemindersFragment : Fragment() {
(root.circulars_list.adapter as CircularLetterAdapter).changeDataSet(it) (root.circulars_list.adapter as CircularLetterAdapter).changeDataSet(it)
} }
}) })
(activity as MainActivity).searchCallback = this
return root return root
} }
override fun search(query: String) {
remindersViewModel.query.postValue(query)
}
} }

View File

@@ -22,6 +22,7 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import net.underdesk.circolapp.data.AppDatabase import net.underdesk.circolapp.data.AppDatabase
import net.underdesk.circolapp.data.Circular import net.underdesk.circolapp.data.Circular
import net.underdesk.circolapp.server.DataFetcher import net.underdesk.circolapp.server.DataFetcher
@@ -36,8 +37,14 @@ class CircularLetterViewModel(application: Application) : AndroidViewModel(appli
}.start() }.start()
} }
val circulars: LiveData<List<Circular>> = val query = MutableLiveData<String>("")
val circulars: LiveData<List<Circular>> = Transformations.switchMap(query) { input ->
if (input == null || input == "") {
AppDatabase.getInstance(getApplication()).circularDao().getLiveCirculars() AppDatabase.getInstance(getApplication()).circularDao().getLiveCirculars()
} else {
AppDatabase.getInstance(getApplication()).circularDao().searchCirculars("%$input%")
}
}
val showMessage = MutableLiveData<Boolean>().apply { value = false } val showMessage = MutableLiveData<Boolean>().apply { value = false }

View File

@@ -21,10 +21,18 @@ package net.underdesk.circolapp.viewmodels
import android.app.Application import android.app.Application
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import net.underdesk.circolapp.data.AppDatabase import net.underdesk.circolapp.data.AppDatabase
import net.underdesk.circolapp.data.Circular import net.underdesk.circolapp.data.Circular
class FavouritesViewModel(application: Application) : AndroidViewModel(application) { class FavouritesViewModel(application: Application) : AndroidViewModel(application) {
val circulars: LiveData<List<Circular>> = val query = MutableLiveData<String>("")
val circulars: LiveData<List<Circular>> = Transformations.switchMap(query) { input ->
if (input == null || input == "") {
AppDatabase.getInstance(getApplication()).circularDao().getFavourites() AppDatabase.getInstance(getApplication()).circularDao().getFavourites()
} else {
AppDatabase.getInstance(getApplication()).circularDao().searchFavourites("%$input%")
}
}
} }

View File

@@ -21,10 +21,18 @@ package net.underdesk.circolapp.viewmodels
import android.app.Application import android.app.Application
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import net.underdesk.circolapp.data.AppDatabase import net.underdesk.circolapp.data.AppDatabase
import net.underdesk.circolapp.data.Circular import net.underdesk.circolapp.data.Circular
class RemindersViewModel(application: Application) : AndroidViewModel(application) { class RemindersViewModel(application: Application) : AndroidViewModel(application) {
val circulars: LiveData<List<Circular>> = val query = MutableLiveData<String>("")
val circulars: LiveData<List<Circular>> = Transformations.switchMap(query) { input ->
if (input == null || input == "") {
AppDatabase.getInstance(getApplication()).circularDao().getReminders() AppDatabase.getInstance(getApplication()).circularDao().getReminders()
} else {
AppDatabase.getInstance(getApplication()).circularDao().searchReminders("%$input%")
}
}
} }

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
</vector>

View File

@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_main_search"
android:icon="@drawable/ic_search_black_24dp"
android:title="@string/menu_search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="ifRoom" />
<item <item
android:id="@+id/menu_main_about" android:id="@+id/menu_main_about"
android:title="@string/menu_about" /> android:title="@string/menu_about" />

View File

@@ -6,6 +6,7 @@
<string name="title_licenses">Third party licenses</string> <string name="title_licenses">Third party licenses</string>
<string name="menu_about">About</string> <string name="menu_about">About</string>
<string name="menu_search">Search</string>
<string name="notification_title">Circular letter number %1$d</string> <string name="notification_title">Circular letter number %1$d</string>
<string name="notification_summary_title">New circulars published</string> <string name="notification_summary_title">New circulars published</string>