Added clear button in search

This commit is contained in:
h4h13 2019-11-30 16:42:47 +05:30
parent 778ec942a5
commit 4da1f68617
2 changed files with 198 additions and 171 deletions

View file

@ -1,215 +1,225 @@
package code.name.monkey.retromusic.activities package code.name.monkey.retromusic.activities
import android.app.* import android.app.Activity
import android.content.* import android.app.Service
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.os.Bundle import android.os.Bundle
import android.speech.RecognizerIntent import android.speech.RecognizerIntent
import android.text.* import android.text.Editable
import android.text.TextWatcher
import android.view.View import android.view.View
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import android.widget.TextView.BufferType import android.widget.TextView.BufferType
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.widget.SearchView.OnQueryTextListener import androidx.appcompat.widget.SearchView.OnQueryTextListener
import androidx.recyclerview.widget.* import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.TransitionManager
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.* import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.* import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.adapter.SearchAdapter import code.name.monkey.retromusic.adapter.SearchAdapter
import code.name.monkey.retromusic.mvp.presenter.* import code.name.monkey.retromusic.mvp.presenter.SearchPresenter
import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.mvp.presenter.SearchView
import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.google.android.material.textfield.TextInputEditText
import kotlinx.android.synthetic.main.activity_search.* import kotlinx.android.synthetic.main.activity_search.*
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatcher, SearchView { class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatcher, SearchView {
@Inject @Inject
lateinit var searchPresenter: SearchPresenter lateinit var searchPresenter: SearchPresenter
private var searchAdapter: SearchAdapter? = null private var searchAdapter: SearchAdapter? = null
private var query: String? = null private var query: String? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar() setDrawUnderStatusBar()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search) setContentView(R.layout.activity_search)
App.musicComponent.inject(this) App.musicComponent.inject(this)
searchPresenter.attachView(this) searchPresenter.attachView(this)
setStatusbarColorAuto() setStatusbarColorAuto()
setNavigationBarColorPrimary() setNavigationBarColorPrimary()
setTaskDescriptionColorAuto() setTaskDescriptionColorAuto()
setLightNavigationBar(true) setLightNavigationBar(true)
setupRecyclerView() setupRecyclerView()
setUpToolBar() setUpToolBar()
setupSearchView() setupSearchView()
if (intent.getBooleanExtra(EXTRA_SHOW_MIC, false)) { if (intent.getBooleanExtra(EXTRA_SHOW_MIC, false)) {
startMicSearch() startMicSearch()
} }
back.setOnClickListener { onBackPressed() } back.setOnClickListener { onBackPressed() }
voiceSearch.setOnClickListener { startMicSearch() } voiceSearch.setOnClickListener { startMicSearch() }
clearText.setOnClickListener { searchView.clearText() }
searchContainer.setCardBackgroundColor(RetroColorUtil.toolbarColor(this))
searchContainer.setCardBackgroundColor(RetroColorUtil.toolbarColor(this)) keyboardPopup.setOnClickListener {
val inputManager = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager
inputManager.showSoftInput(searchView, InputMethodManager.SHOW_IMPLICIT)
}
keyboardPopup.setOnClickListener { keyboardPopup.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
val inputManager = getSystemService(Service.INPUT_METHOD_SERVICE) as InputMethodManager ColorStateList.valueOf(
inputManager.showSoftInput(searchView, InputMethodManager.SHOW_IMPLICIT) MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(ThemeStore.accentColor(this)))
} ).apply {
keyboardPopup.setTextColor(this)
keyboardPopup.iconTint = this
}
if (savedInstanceState != null) {
query = savedInstanceState.getString(QUERY);
}
keyboardPopup.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this)) }
ColorStateList.valueOf(
MaterialValueHelper.getPrimaryTextColor(
this,
ColorUtil.isColorLight(
ThemeStore.accentColor(
this
)
)
)
).apply {
keyboardPopup.setTextColor(this)
keyboardPopup.iconTint = this
}
if (savedInstanceState != null) {
query = savedInstanceState.getString(QUERY);
}
} private fun setupRecyclerView() {
searchAdapter = SearchAdapter(this, emptyList())
searchAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
empty.visibility = if (searchAdapter!!.itemCount < 1) View.VISIBLE else View.GONE
}
})
recyclerView.apply {
layoutManager = LinearLayoutManager(this@SearchActivity)
adapter = searchAdapter
}
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (dy > 0) {
keyboardPopup.shrink()
} else if (dy < 0) {
keyboardPopup.extend()
}
}
})
}
private fun setupRecyclerView() { private fun setupSearchView() {
searchAdapter = SearchAdapter(this, emptyList()) searchView.addTextChangedListener(this)
searchAdapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { }
override fun onChanged() {
super.onChanged()
empty.visibility = if (searchAdapter!!.itemCount < 1) View.VISIBLE else View.GONE
}
})
recyclerView.apply {
layoutManager = LinearLayoutManager(this@SearchActivity)
adapter = searchAdapter
}
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (dy > 0) {
keyboardPopup.shrink()
} else if (dy < 0) {
keyboardPopup.extend()
}
}
})
}
private fun setupSearchView() { override fun onDestroy() {
searchView.addTextChangedListener(this) super.onDestroy()
} searchPresenter.detachView()
}
override fun onDestroy() { override fun onSaveInstanceState(outState: Bundle) {
super.onDestroy() super.onSaveInstanceState(outState)
searchPresenter.detachView() outState.putString(QUERY, query)
} }
override fun onSaveInstanceState(outState: Bundle) { private fun setUpToolBar() {
super.onSaveInstanceState(outState) title = null
outState.putString(QUERY, query) appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
} }
private fun setUpToolBar() { private fun search(query: String) {
title = null this.query = query
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary)) TransitionManager.beginDelayedTransition(appBarLayout)
} voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
clearText.visibility = if (query.isNotEmpty()) View.VISIBLE else View.GONE
searchPresenter.search(query)
}
private fun search(query: String) { override fun onMediaStoreChanged() {
this.query = query super.onMediaStoreChanged()
voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE query?.let { search(it) }
searchPresenter.search(query) }
}
override fun onMediaStoreChanged() { override fun onQueryTextSubmit(query: String): Boolean {
super.onMediaStoreChanged() hideSoftKeyboard()
query?.let { search(it) } return false
} }
override fun onQueryTextSubmit(query: String): Boolean { override fun onQueryTextChange(newText: String): Boolean {
hideSoftKeyboard() search(newText)
return false return false
} }
override fun onQueryTextChange(newText: String): Boolean { private fun hideSoftKeyboard() {
search(newText) RetroUtil.hideSoftKeyboard(this@SearchActivity)
return false if (searchView != null) {
} searchView.clearFocus()
}
}
private fun hideSoftKeyboard() { override fun showEmptyView() {
RetroUtil.hideSoftKeyboard(this@SearchActivity) searchAdapter?.swapDataSet(ArrayList())
if (searchView != null) { }
searchView.clearFocus()
}
}
override fun showEmptyView() { override fun showData(data: MutableList<Any>) {
searchAdapter?.swapDataSet(ArrayList()) searchAdapter?.swapDataSet(data)
} }
override fun showData(data: MutableList<Any>) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
searchAdapter?.swapDataSet(data) super.onActivityResult(requestCode, resultCode, data)
} when (requestCode) {
REQ_CODE_SPEECH_INPUT -> {
if (resultCode == Activity.RESULT_OK && null != data) {
val result: ArrayList<String>? = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)
query = result?.get(0)
searchView.setText(query, BufferType.EDITABLE)
searchPresenter.search(query!!)
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private fun startMicSearch() {
super.onActivityResult(requestCode, resultCode, data) val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
when (requestCode) { intent.putExtra(
REQ_CODE_SPEECH_INPUT -> { RecognizerIntent.EXTRA_LANGUAGE_MODEL,
if (resultCode == Activity.RESULT_OK && null != data) { RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
val result: ArrayList<String>? = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) )
query = result?.get(0) intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
searchView.setText(query, BufferType.EDITABLE) intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt))
searchPresenter.search(query!!) try {
} startActivityForResult(intent, REQ_CODE_SPEECH_INPUT)
} } catch (e: ActivityNotFoundException) {
} e.printStackTrace()
} Toast.makeText(this, getString(R.string.speech_not_supported), Toast.LENGTH_SHORT)
.show()
}
private fun startMicSearch() { }
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
)
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt))
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
Toast.makeText(this, getString(R.string.speech_not_supported), Toast.LENGTH_SHORT)
.show()
}
} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { }
} override fun onTextChanged(newText: CharSequence, start: Int, before: Int, count: Int) {
search(newText.toString())
}
override fun onTextChanged(newText: CharSequence, start: Int, before: Int, count: Int) { override fun afterTextChanged(s: Editable) {
search(newText.toString())
}
override fun afterTextChanged(s: Editable) { }
} companion object {
val TAG: String = SearchActivity::class.java.simpleName
companion object { const val EXTRA_SHOW_MIC = "extra_show_mic"
val TAG: String = SearchActivity::class.java.simpleName const val QUERY: String = "query"
const val EXTRA_SHOW_MIC = "extra_show_mic" private const val REQ_CODE_SPEECH_INPUT = 9002
const val QUERY: String = "query" }
private const val REQ_CODE_SPEECH_INPUT = 9002
}
} }
fun TextInputEditText.clearText() {
text = null
}

View file

@ -55,16 +55,33 @@
<requestFocus /> <requestFocus />
</com.google.android.material.textfield.TextInputEditText> </com.google.android.material.textfield.TextInputEditText>
<androidx.appcompat.widget.AppCompatImageView <FrameLayout
android:id="@+id/voiceSearch"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0" android:layout_weight="0">
android:background="?roundSelector"
android:padding="12dp" <androidx.appcompat.widget.AppCompatImageView
app:srcCompat="@drawable/ic_mic_white_24dp" android:id="@+id/voiceSearch"
app:tint="?colorOnSurface" android:layout_width="wrap_content"
tools:visibility="visible" /> android:layout_height="wrap_content"
android:background="?roundSelector"
android:padding="12dp"
app:srcCompat="@drawable/ic_mic_white_24dp"
app:tint="?colorOnSurface"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/clearText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?roundSelector"
android:padding="12dp"
app:srcCompat="@drawable/ic_close_white_24dp"
app:tint="?colorOnSurface"
android:visibility="gone"
tools:visibility="visible" />
</FrameLayout>
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>