Skip to content

Commit

Permalink
Add local song search (filter)
Browse files Browse the repository at this point in the history
  • Loading branch information
Senorsen committed Aug 29, 2017
1 parent 79e22b2 commit d03cf68
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 36 deletions.
2 changes: 1 addition & 1 deletion wukong/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ android {
minSdkVersion 21
targetSdkVersion 25
versionCode 141
versionName "0.1.45"
versionName "0.1.46"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down
68 changes: 46 additions & 22 deletions wukong/src/main/java/com/senorsen/wukong/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ import android.preference.PreferenceManager
import android.support.design.widget.NavigationView
import android.support.v4.content.LocalBroadcastManager
import android.support.v4.view.GravityCompat
import android.support.v4.view.MenuItemCompat
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.SearchView
import android.support.v7.widget.Toolbar
import android.text.Html
import android.text.InputType
import android.text.SpannableStringBuilder
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.EditText
Expand All @@ -32,7 +35,6 @@ import android.widget.Toast
import com.github.javiersantos.appupdater.AppUpdater
import com.github.javiersantos.appupdater.enums.UpdateFrom
import com.senorsen.wukong.R
import com.senorsen.wukong.model.Message
import com.senorsen.wukong.model.User
import com.senorsen.wukong.network.HttpClient
import com.senorsen.wukong.service.WukongService
Expand Down Expand Up @@ -232,6 +234,14 @@ class MainActivity : AppCompatActivity() {
mDrawerToggle.onConfigurationChanged(newConfig)
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
val search = menu.findItem(R.id.search)
val searchView = MenuItemCompat.getActionView(search) as SearchView
search(searchView)
return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
Log.d(TAG, "onOptionsItemSelected $item")
when (item.itemId) {
Expand All @@ -242,8 +252,8 @@ class MainActivity : AppCompatActivity() {
showChannelDialog()

R.id.nav_settings -> {
val currentFragment = fragmentManager.findFragmentByTag("SETTINGS")
if (currentFragment == null || !currentFragment.isVisible) {
val settingsFragment = getSettingsFragment()
if (settingsFragment == null || !settingsFragment.isVisible) {
fragmentManager.beginTransaction()
.replace(R.id.fragment, SettingsFragment(), "SETTINGS")
.addToBackStack("tag")
Expand All @@ -258,32 +268,46 @@ class MainActivity : AppCompatActivity() {
stopService(Intent(this, WukongService::class.java))

R.id.nav_sync_playlist -> {
val currentFragment = fragmentManager.findFragmentByTag("MAIN")
if (currentFragment != null) {
val fragment = currentFragment as MainFragment
val childFragment = fragment.childFragmentManager.findFragmentByTag("SONGLIST")
if (childFragment != null) {
val songListFragment = childFragment as SongListFragment
songListFragment.fetchSongList()
}
}
getSongListFragment()?.fetchSongList()
}

R.id.nav_clear_playlist -> {
val currentFragment = fragmentManager.findFragmentByTag("MAIN")
if (currentFragment != null) {
val fragment = currentFragment as MainFragment
val childFragment = fragment.childFragmentManager.findFragmentByTag("SONGLIST")
if (childFragment != null) {
val songListFragment = childFragment as SongListFragment
songListFragment.clearSongList()
}
}
getSongListFragment()?.clearSongList()
}
}
return super.onOptionsItemSelected(item)
}

private fun getSettingsFragment() : SettingsFragment? {
return fragmentManager.findFragmentByTag("SETTINGS") as SettingsFragment
}

private fun getSongListFragment(): SongListFragment? {
val currentFragment = fragmentManager.findFragmentByTag("MAIN")
if (currentFragment != null) {
val fragment = currentFragment as MainFragment
val childFragment = fragment.childFragmentManager.findFragmentByTag("SONGLIST")
if (childFragment != null) {
return childFragment as SongListFragment
}
}
return null
}

private fun search(searchView: SearchView) {
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}

override fun onQueryTextChange(newText: String): Boolean {
Log.i(TAG, "search $newText")
getSongListFragment()?.adapter?.filter?.filter(newText)
return true
}
})
}

override fun onResume() {
super.onResume()
if (broadcastReceiver == null) broadcastReceiver = ChannelUpdateBroadcastReceiver()
Expand Down Expand Up @@ -342,7 +366,7 @@ class MainActivity : AppCompatActivity() {
Html.fromHtml("<b>${users.size}</b> player${if (users.size > 1) "s" else ""}: "
+ users.map { if (it.id == currentPlayUserId) "<b>${it.userName}</b>" else it.userName }.joinToString())
else
Html.fromHtml("disconnected")
Html.fromHtml("Disconnected")
}

fun updateSongList() {
Expand Down
54 changes: 44 additions & 10 deletions wukong/src/main/java/com/senorsen/wukong/ui/SongListFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import android.widget.*
import com.senorsen.wukong.R
import com.senorsen.wukong.model.Song
import com.senorsen.wukong.network.HttpClient
Expand All @@ -32,7 +30,7 @@ import kotlin.concurrent.thread
class SongListFragment : Fragment() {

private val handler = Handler()
private val adapter = SongListAdapter(this)
val adapter = SongListAdapter(this)
var connected = false
var wukongService: WukongService? = null
private lateinit var songListLocalStore: SongListLocalStore
Expand Down Expand Up @@ -180,18 +178,27 @@ class SongListFragment : Fragment() {
super.onStop()
}

private class SongListAdapter(val fragment: SongListFragment) : RecyclerView.Adapter<SongListAdapter.ViewHolder>() {
class SongListAdapter(val fragment: SongListFragment) : RecyclerView.Adapter<SongListAdapter.ViewHolder>(), Filterable {

var lastNeedle: String? = null

var list: List<Song>? = null
get() = field
set(value) {
field = value
notifyDataSetChanged()
filter.filter(lastNeedle ?: "")
fragment.songListLocalStore.save(value)
}

private var filteredList: List<Song>? = null
get() = field
set(value) {
field = value
notifyDataSetChanged()
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val song = list?.get(position) ?: return
val song = filteredList?.getOrNull(position) ?: return
holder.name.text = song.title
holder.caption.text = "${song.artist} - ${song.album}"
holder.id = position
Expand All @@ -204,6 +211,34 @@ class SongListFragment : Fragment() {

override fun getItemCount() = list?.size ?: 0

override fun getFilter(): Filter {
return object : Filter() {

override fun performFiltering(constraint: CharSequence): FilterResults {
val needle = constraint.toString().toLowerCase()
lastNeedle = needle
val resultList = if (needle.isBlank()) {
list
} else {
list?.filter {
it.title?.toLowerCase()?.contains(needle) ?: false
|| it.album?.toLowerCase()?.contains(needle) ?: false
|| it.artist?.toLowerCase()?.contains(needle) ?: false
|| it.songId == needle
}
}
val filterResults = FilterResults()
filterResults.values = resultList
return filterResults
}

@Suppress("UNCHECKED_CAST")
override fun publishResults(constraint: CharSequence, results: FilterResults) {
filteredList = results.values as List<Song>?
}
}
}

inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {

val icon = view.findViewById(android.R.id.icon) as ImageView
Expand All @@ -217,7 +252,7 @@ class SongListFragment : Fragment() {
upIcon.setOnClickListener {
Log.d(TAG, "up $id")
val tempList = list!!.toMutableList()
val song = tempList[id]
val song = filteredList!![id]
tempList.remove(song)
tempList.add(0, song)
list = tempList
Expand All @@ -229,15 +264,14 @@ class SongListFragment : Fragment() {
removeIcon.setOnClickListener {
Log.d(TAG, "remove $id")
val tempList = list!!.toMutableList()
val song = tempList[id]
val song = filteredList!![id]
tempList.remove(song)
list = tempList

fragment.wukongService?.userSongList = tempList
fragment.wukongService?.doUpdateNextSong()
}
}

}
}
}
Binary file added wukong/src/main/res/drawable-hdpi/ic_search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wukong/src/main/res/drawable-mdpi/ic_search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added wukong/src/main/res/drawable-xhdpi/ic_search.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
android:viewportHeight="24.0">
<path
android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z"
android:fillColor="#000000"/>
android:fillColor="#666"/>
</vector>
2 changes: 1 addition & 1 deletion wukong/src/main/res/drawable/ic_remove_song_24dp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:fillColor="#666"
android:pathData="M7,11v2h10v-2L7,11zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>
2 changes: 1 addition & 1 deletion wukong/src/main/res/layout/fragment_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
android:layout_height="wrap_content"
android:singleLine="false"
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
android:text="disconnected" />
android:text="Disconnected" />


</LinearLayout>
Expand Down
1 change: 1 addition & 0 deletions wukong/src/main/res/layout/item_song.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
android:textColor="#666"
tools:text="孙燕姿:我怀念的" />
</LinearLayout>

Expand Down
12 changes: 12 additions & 0 deletions wukong/src/main/res/menu/menu_main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.senorsen.wukong.ui.MainActivity">
<item
android:id="@+id/search"
android:icon="@drawable/ic_search"
android:title="Search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>

0 comments on commit d03cf68

Please sign in to comment.