added search bar
This commit is contained in:
parent
a1cb810609
commit
53bc051bc1
6 changed files with 115 additions and 118 deletions
|
|
@ -123,7 +123,7 @@ dependencies {
|
||||||
|
|
||||||
implementation "androidx.appcompat:appcompat:$appCompatVer"
|
implementation "androidx.appcompat:appcompat:$appCompatVer"
|
||||||
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
|
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
|
||||||
implementation 'com.google.android.material:material:1.8.0'
|
implementation 'com.google.android.material:material:1.9.0-alpha02'
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
implementation 'androidx.core:core:1.9.0'
|
implementation 'androidx.core:core:1.9.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import android.view.View.VISIBLE
|
||||||
import android.widget.*
|
import android.widget.*
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
import androidx.core.widget.addTextChangedListener
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
|
@ -40,6 +41,7 @@ import com.google.android.material.appbar.AppBarLayout
|
||||||
import com.google.android.material.appbar.MaterialToolbar
|
import com.google.android.material.appbar.MaterialToolbar
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
|
import com.google.android.material.search.SearchBar
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
@ -69,7 +71,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
private var fragmentContext: Context? = null
|
private var fragmentContext: Context? = null
|
||||||
private var layoutinflater: LayoutInflater? = null
|
private var layoutinflater: LayoutInflater? = null
|
||||||
private var shimmerCards: ShimmerFrameLayout? = null
|
private var shimmerCards: ShimmerFrameLayout? = null
|
||||||
private var topAppBar: MaterialToolbar? = null
|
private var searchBar: SearchBar? = null
|
||||||
private var recyclerView: RecyclerView? = null
|
private var recyclerView: RecyclerView? = null
|
||||||
private var uiHandler: Handler? = null
|
private var uiHandler: Handler? = null
|
||||||
private var resultsList: List<ResultItem?>? = null
|
private var resultsList: List<ResultItem?>? = null
|
||||||
|
|
@ -98,7 +100,6 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
|
|
||||||
fragmentContext = context
|
fragmentContext = context
|
||||||
layoutinflater = LayoutInflater.from(context)
|
layoutinflater = LayoutInflater.from(context)
|
||||||
topAppBar = view.findViewById(R.id.downloads_toolbar)
|
|
||||||
fileUtil = FileUtil()
|
fileUtil = FileUtil()
|
||||||
uiHandler = Handler(Looper.getMainLooper())
|
uiHandler = Handler(Looper.getMainLooper())
|
||||||
selectedObjects = ArrayList()
|
selectedObjects = ArrayList()
|
||||||
|
|
@ -113,7 +114,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
|
|
||||||
//initViews
|
//initViews
|
||||||
shimmerCards = view.findViewById(R.id.shimmer_results_framelayout)
|
shimmerCards = view.findViewById(R.id.shimmer_results_framelayout)
|
||||||
topAppBar = view.findViewById(R.id.home_toolbar)
|
searchBar = view.findViewById(R.id.search_bar)
|
||||||
searchSuggestions = view.findViewById(R.id.search_suggestions_scroll_view)
|
searchSuggestions = view.findViewById(R.id.search_suggestions_scroll_view)
|
||||||
searchSuggestionsLinearLayout = view.findViewById(R.id.search_suggestions_linear_layout)
|
searchSuggestionsLinearLayout = view.findViewById(R.id.search_suggestions_linear_layout)
|
||||||
|
|
||||||
|
|
@ -220,101 +221,84 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initMenu() {
|
private fun initMenu() {
|
||||||
val onActionExpandListener: MenuItem.OnActionExpandListener =
|
val searchView = requireView().findViewById<com.google.android.material.search.SearchView>(R.id.search_view)
|
||||||
object : MenuItem.OnActionExpandListener {
|
|
||||||
override fun onMenuItemActionExpand(menuItem: MenuItem): Boolean {
|
|
||||||
homeFabs!!.visibility = GONE
|
|
||||||
recyclerView!!.visibility = GONE
|
|
||||||
searchSuggestions!!.visibility = VISIBLE
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMenuItemActionCollapse(menuItem: MenuItem): Boolean {
|
|
||||||
homeFabs!!.visibility = VISIBLE
|
|
||||||
recyclerView!!.visibility = VISIBLE
|
|
||||||
searchSuggestions!!.visibility = GONE
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (downloading) {
|
|
||||||
topAppBar!!.menu.findItem(R.id.cancel_download).isVisible = true
|
|
||||||
}
|
|
||||||
topAppBar!!.menu.findItem(R.id.search).setOnActionExpandListener(onActionExpandListener)
|
|
||||||
val searchView = topAppBar!!.menu.findItem(R.id.search).actionView as SearchView?
|
|
||||||
searchView!!.inputType = InputType.TYPE_TEXT_VARIATION_URI
|
|
||||||
searchView.queryHint = getString(R.string.search_hint)
|
|
||||||
infoUtil = InfoUtil(requireContext())
|
infoUtil = InfoUtil(requireContext())
|
||||||
|
|
||||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
searchView.editText.addTextChangedListener {
|
||||||
override fun onQueryTextSubmit(query: String): Boolean {
|
searchSuggestionsLinearLayout!!.removeAllViews()
|
||||||
topAppBar!!.menu.findItem(R.id.search).collapseActionView()
|
lifecycleScope.launch {
|
||||||
downloadAllFabCoordinator!!.visibility = GONE
|
val suggestions = withContext(Dispatchers.IO){
|
||||||
downloadFabs!!.visibility = GONE
|
if (it!!.isEmpty()) {
|
||||||
selectedObjects = ArrayList()
|
|
||||||
inputQuery = query.trim { it <= ' ' }
|
|
||||||
if(!sharedPreferences!!.getBoolean("incognito", false)){
|
|
||||||
resultViewModel.addSearchQueryToHistory(inputQuery!!)
|
|
||||||
}
|
|
||||||
resultViewModel.deleteAll()
|
|
||||||
lifecycleScope.launch(Dispatchers.IO){
|
|
||||||
resultViewModel.parseQuery(inputQuery!!, true)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: String): Boolean {
|
|
||||||
searchSuggestionsLinearLayout!!.removeAllViews()
|
|
||||||
val thread = Thread {
|
|
||||||
val suggestions = if (newText.isEmpty()) {
|
|
||||||
resultViewModel.getSearchHistory().map { it.query }
|
resultViewModel.getSearchHistory().map { it.query }
|
||||||
}else{
|
}else{
|
||||||
infoUtil!!.getSearchSuggestions(newText)
|
infoUtil!!.getSearchSuggestions(it.toString())
|
||||||
}
|
}
|
||||||
for (i in suggestions.indices) {
|
}
|
||||||
val v = LayoutInflater.from(fragmentContext)
|
|
||||||
.inflate(R.layout.search_suggestion_item, null)
|
for (i in suggestions.indices) {
|
||||||
val textView = v.findViewById<TextView>(R.id.suggestion_text)
|
val v = LayoutInflater.from(fragmentContext)
|
||||||
textView.text = suggestions[i]
|
.inflate(R.layout.search_suggestion_item, null)
|
||||||
Handler(Looper.getMainLooper()).post {
|
val textView = v.findViewById<TextView>(R.id.suggestion_text)
|
||||||
searchSuggestionsLinearLayout!!.addView(
|
textView.text = suggestions[i]
|
||||||
v
|
Handler(Looper.getMainLooper()).post {
|
||||||
)
|
searchSuggestionsLinearLayout!!.addView(
|
||||||
}
|
v
|
||||||
textView.setOnClickListener { onQueryTextSubmit(textView.text.toString()) }
|
)
|
||||||
val mb = v.findViewById<MaterialButton>(R.id.set_search_query_button)
|
}
|
||||||
mb.setOnClickListener {
|
textView.setOnClickListener {
|
||||||
searchView.setQuery(
|
searchView.setText(textView.text)
|
||||||
textView.text,
|
initSearch(searchView)
|
||||||
false
|
}
|
||||||
)
|
val mb = v.findViewById<ImageButton>(R.id.set_search_query_button)
|
||||||
}
|
mb.setOnClickListener {
|
||||||
|
searchView.setText(textView.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thread.start()
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
})
|
false
|
||||||
topAppBar!!.setOnClickListener { scrollToTop() }
|
}
|
||||||
topAppBar!!.setOnMenuItemClickListener { m: MenuItem ->
|
|
||||||
val itemId = m.itemId
|
searchView.editText.setOnEditorActionListener { textView, i, keyEvent ->
|
||||||
if (itemId == R.id.delete_results) {
|
initSearch(searchView)
|
||||||
resultViewModel.getTrending()
|
true
|
||||||
selectedObjects = ArrayList()
|
}
|
||||||
downloadAllFabCoordinator!!.visibility = GONE
|
|
||||||
downloadFabs!!.visibility = GONE
|
searchBar!!.setOnMenuItemClickListener { m: MenuItem ->
|
||||||
} else if (itemId == R.id.cancel_download) {
|
when (val itemId = m.itemId) {
|
||||||
try {
|
R.id.delete_results -> {
|
||||||
mainActivity!!.cancelAllDownloads()
|
resultViewModel.getTrending()
|
||||||
topAppBar!!.menu.findItem(itemId).isVisible = false
|
selectedObjects = ArrayList()
|
||||||
} catch (ignored: Exception) {}
|
downloadAllFabCoordinator!!.visibility = GONE
|
||||||
} else if (itemId == R.id.delete_search){
|
downloadFabs!!.visibility = GONE
|
||||||
resultViewModel.deleteAllSearchQueryHistory()
|
}
|
||||||
searchSuggestionsLinearLayout!!.removeAllViews()
|
R.id.cancel_download -> {
|
||||||
|
try {
|
||||||
|
mainActivity!!.cancelAllDownloads()
|
||||||
|
searchBar!!.menu.findItem(itemId).isVisible = false
|
||||||
|
} catch (ignored: Exception) {}
|
||||||
|
}
|
||||||
|
R.id.delete_search -> {
|
||||||
|
resultViewModel.deleteAllSearchQueryHistory()
|
||||||
|
searchSuggestionsLinearLayout!!.removeAllViews()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initSearch(searchView: com.google.android.material.search.SearchView){
|
||||||
|
searchBar!!.text = searchView.text
|
||||||
|
searchView.hide()
|
||||||
|
val inputQuery = searchView.text!!.trim { it <= ' '}
|
||||||
|
if(!sharedPreferences!!.getBoolean("incognito", false)){
|
||||||
|
resultViewModel.addSearchQueryToHistory(inputQuery.toString())
|
||||||
|
}
|
||||||
|
resultViewModel.deleteAll()
|
||||||
|
lifecycleScope.launch(Dispatchers.IO){
|
||||||
|
resultViewModel.parseQuery(inputQuery.toString(), true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun handleIntent(intent: Intent) {
|
fun handleIntent(intent: Intent) {
|
||||||
inputQueries = LinkedList()
|
inputQueries = LinkedList()
|
||||||
inputQueries!!.add(intent.getStringExtra(Intent.EXTRA_TEXT))
|
inputQueries!!.add(intent.getStringExtra(Intent.EXTRA_TEXT))
|
||||||
|
|
@ -326,7 +310,7 @@ class HomeFragment : Fragment(), HomeAdapter.OnItemClickListener, View.OnClickLi
|
||||||
|
|
||||||
fun scrollToTop() {
|
fun scrollToTop() {
|
||||||
recyclerView!!.scrollToPosition(0)
|
recyclerView!!.scrollToPosition(0)
|
||||||
(topAppBar!!.parent as AppBarLayout).setExpanded(true, true)
|
(searchBar!!.parent as AppBarLayout).setExpanded(true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findVideo(url: String): ResultItem? {
|
private fun findVideo(url: String): ResultItem? {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,30 @@
|
||||||
android:id="@+id/homecoordinator"
|
android:id="@+id/homecoordinator"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<com.google.android.material.search.SearchView
|
||||||
|
android:id="@+id/search_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:hint="@string/search_hint"
|
||||||
|
app:layout_anchor="@id/search_bar">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/search_suggestions_scroll_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/search_suggestions_linear_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<include layout="@layout/search_suggestion_item" />
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<!-- Search suggestions/results go here (ScrollView, RecyclerView, etc.). -->
|
||||||
|
</com.google.android.material.search.SearchView>
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/home_appbarlayout"
|
android:id="@+id/home_appbarlayout"
|
||||||
app:liftOnScroll="true"
|
app:liftOnScroll="true"
|
||||||
|
|
@ -14,32 +38,21 @@
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/home_toolbar"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
|
||||||
app:layout_scrollFlags="scroll|enterAlways|snap"
|
|
||||||
app:title="@string/app_name"
|
app:title="@string/app_name"
|
||||||
app:menu="@menu/main_menu"
|
app:layout_scrollFlags="scroll"
|
||||||
android:theme="@style/Toolbar"
|
android:theme="@style/Toolbar"
|
||||||
/>
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
<com.google.android.material.search.SearchBar
|
||||||
|
android:id="@+id/search_bar"
|
||||||
<ScrollView
|
app:menu="@menu/main_menu"
|
||||||
android:id="@+id/search_suggestions_scroll_view"
|
app:layout_scrollFlags="scroll|enterAlways"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:layout_marginTop="?attr/actionBarSize"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/search_suggestions_linear_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:hint="@string/search_hint" />
|
||||||
|
|
||||||
<include layout="@layout/search_suggestion_item" />
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,13 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<ImageButton
|
||||||
style="?attr/materialIconButtonStyle"
|
style="?attr/materialIconButtonStyle"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:scrollbars="none"
|
android:scrollbars="none"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0.01"
|
android:layout_weight="0.01"
|
||||||
app:icon="@drawable/ic_search"
|
android:src="@drawable/ic_search"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
@ -51,13 +51,13 @@
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Button
|
<ImageButton
|
||||||
style="?attr/materialIconButtonStyle"
|
style="?attr/materialIconButtonStyle"
|
||||||
android:id="@+id/set_search_query_button"
|
android:id="@+id/set_search_query_button"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
android:scrollbars="none"
|
android:scrollbars="none"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:icon="@drawable/ic_arrow_up"
|
android:src="@drawable/ic_arrow_up"
|
||||||
android:layout_weight="0.01"
|
android:layout_weight="0.01"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context=".MainActivity" >
|
tools:context=".MainActivity" >
|
||||||
|
|
||||||
<item
|
<!-- <item-->
|
||||||
android:id="@+id/search"
|
<!-- android:id="@+id/search"-->
|
||||||
android:title="@string/search"
|
<!-- android:title="@string/search"-->
|
||||||
android:icon="@drawable/ic_search"
|
<!-- android:icon="@drawable/ic_search"-->
|
||||||
app:showAsAction="always|collapseActionView"
|
<!-- app:showAsAction="always|collapseActionView"-->
|
||||||
app:actionViewClass="androidx.appcompat.widget.SearchView"/>
|
<!-- app:actionViewClass="androidx.appcompat.widget.SearchView"/>-->
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/delete_results"
|
android:id="@+id/delete_results"
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<string name="update_ytdl">Install new version of yt-dlp</string>
|
<string name="update_ytdl">Install new version of yt-dlp</string>
|
||||||
<string name="about">About</string>
|
<string name="about">About</string>
|
||||||
<string name="source_code">Source Code</string>
|
<string name="source_code">Source Code</string>
|
||||||
<string name="search_hint">Search from YouTube</string>
|
<string name="search_hint">Search or Insert URL</string>
|
||||||
<string name="download_already_started">Waiting for other download to finish before starting this one…</string>
|
<string name="download_already_started">Waiting for other download to finish before starting this one…</string>
|
||||||
<string name="try_again_after_permission">Retry after granting the permission.</string>
|
<string name="try_again_after_permission">Retry after granting the permission.</string>
|
||||||
<string name="download_success">Downloaded</string>
|
<string name="download_success">Downloaded</string>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue