Single-provider search
This commit is contained in:
@@ -14,10 +14,10 @@
|
|||||||
android:fullBackupContent="@xml/backup_descriptor"
|
android:fullBackupContent="@xml/backup_descriptor"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:usesCleartextTraffic="true"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme"
|
||||||
|
android:usesCleartextTraffic="true">
|
||||||
<activity android:name=".ui.main.MainActivity">
|
<activity android:name=".ui.main.MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
@@ -29,14 +29,9 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".ui.details.MangaDetailsActivity" />
|
<activity android:name=".ui.details.MangaDetailsActivity" />
|
||||||
<activity android:name=".ui.reader.ReaderActivity" />
|
<activity android:name=".ui.reader.ReaderActivity" />
|
||||||
<activity android:name=".ui.search.SearchActivity">
|
<activity
|
||||||
<intent-filter>
|
android:name=".ui.search.SearchActivity"
|
||||||
<action android:name="android.intent.action.SEARCH" />
|
android:label="@string/search" />
|
||||||
</intent-filter>
|
|
||||||
<meta-data
|
|
||||||
android:name="android.app.searchable"
|
|
||||||
android:resource="@xml/search" />
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.settings.SettingsActivity"
|
android:name=".ui.settings.SettingsActivity"
|
||||||
android:label="@string/settings" />
|
android:label="@string/settings" />
|
||||||
@@ -44,7 +39,7 @@
|
|||||||
<service android:name=".ui.download.DownloadService" />
|
<service android:name=".ui.download.DownloadService" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name=".domain.search.MangaSuggestionsProvider"
|
android:name=".ui.search.MangaSuggestionsProvider"
|
||||||
android:authorities="${applicationId}.MangaSuggestionsProvider" />
|
android:authorities="${applicationId}.MangaSuggestionsProvider" />
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.domain.search
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.SearchRecentSuggestionsProvider
|
|
||||||
import android.provider.SearchRecentSuggestions
|
|
||||||
import org.koitharu.kotatsu.BuildConfig
|
|
||||||
|
|
||||||
class MangaSuggestionsProvider : SearchRecentSuggestionsProvider() {
|
|
||||||
|
|
||||||
init {
|
|
||||||
setupSuggestions(AUTHORITY, MODE)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
fun saveQuery(context: Context, query: String) {
|
|
||||||
SearchRecentSuggestions(context, AUTHORITY, MODE)
|
|
||||||
.saveRecentQuery(query, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clearHistory(context: Context) {
|
|
||||||
SearchRecentSuggestions(context, AUTHORITY, MODE)
|
|
||||||
.clearHistory()
|
|
||||||
}
|
|
||||||
|
|
||||||
private const val AUTHORITY = "${BuildConfig.APPLICATION_ID}.MangaSuggestionsProvider"
|
|
||||||
private const val MODE = DATABASE_MODE_QUERIES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,6 @@ import org.koitharu.kotatsu.ui.main.list.history.HistoryListFragment
|
|||||||
import org.koitharu.kotatsu.ui.main.list.local.LocalListFragment
|
import org.koitharu.kotatsu.ui.main.list.local.LocalListFragment
|
||||||
import org.koitharu.kotatsu.ui.main.list.remote.RemoteListFragment
|
import org.koitharu.kotatsu.ui.main.list.remote.RemoteListFragment
|
||||||
import org.koitharu.kotatsu.ui.settings.SettingsActivity
|
import org.koitharu.kotatsu.ui.settings.SettingsActivity
|
||||||
import org.koitharu.kotatsu.utils.SearchHelper
|
|
||||||
|
|
||||||
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener,
|
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener,
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
@@ -65,7 +64,6 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
|||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||||
menuInflater.inflate(R.menu.opt_main, menu)
|
menuInflater.inflate(R.menu.opt_main, menu)
|
||||||
menu?.findItem(R.id.action_search)?.let(SearchHelper::setupSearchView)
|
|
||||||
return super.onCreateOptionsMenu(menu)
|
return super.onCreateOptionsMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package org.koitharu.kotatsu.ui.main.list.remote
|
package org.koitharu.kotatsu.ui.main.list.remote
|
||||||
|
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuInflater
|
||||||
import moxy.ktx.moxyPresenter
|
import moxy.ktx.moxyPresenter
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.model.MangaFilter
|
import org.koitharu.kotatsu.core.model.MangaFilter
|
||||||
import org.koitharu.kotatsu.core.model.MangaSource
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
|
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
|
||||||
|
import org.koitharu.kotatsu.ui.search.SearchHelper
|
||||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
class RemoteListFragment : MangaListFragment<Unit>() {
|
class RemoteListFragment : MangaListFragment<Unit>() {
|
||||||
@@ -25,6 +29,14 @@ class RemoteListFragment : MangaListFragment<Unit>() {
|
|||||||
super.onFilterChanged(filter)
|
super.onFilterChanged(filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
inflater.inflate(R.menu.opt_remote, menu)
|
||||||
|
menu.findItem(R.id.action_search)?.let { menuItem ->
|
||||||
|
SearchHelper.setupSearchView(menuItem, source)
|
||||||
|
}
|
||||||
|
super.onCreateOptionsMenu(menu, inflater)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val ARG_SOURCE = "provider"
|
private const val ARG_SOURCE = "provider"
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.search
|
||||||
|
|
||||||
|
import android.app.SearchManager
|
||||||
|
import android.content.ContentResolver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.SearchRecentSuggestionsProvider
|
||||||
|
import android.database.Cursor
|
||||||
|
import android.net.Uri
|
||||||
|
import android.provider.SearchRecentSuggestions
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.cursoradapter.widget.CursorAdapter
|
||||||
|
import org.koitharu.kotatsu.BuildConfig
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
|
||||||
|
class MangaSuggestionsProvider : SearchRecentSuggestionsProvider() {
|
||||||
|
|
||||||
|
init {
|
||||||
|
setupSuggestions(
|
||||||
|
AUTHORITY,
|
||||||
|
MODE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SearchSuggestionAdapter(context: Context, cursor: Cursor) : CursorAdapter(
|
||||||
|
context, cursor,
|
||||||
|
FLAG_REGISTER_CONTENT_OBSERVER
|
||||||
|
) {
|
||||||
|
|
||||||
|
override fun newView(context: Context, cursor: Cursor?, parent: ViewGroup?): View {
|
||||||
|
return LayoutInflater.from(context)
|
||||||
|
.inflate(R.layout.item_search_complete, parent, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindView(view: View, context: Context, cursor: Cursor) {
|
||||||
|
if (view !is TextView) return
|
||||||
|
view.text = cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun convertToString(cursor: Cursor?): CharSequence {
|
||||||
|
return cursor?.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY))
|
||||||
|
.orEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val AUTHORITY = "${BuildConfig.APPLICATION_ID}.MangaSuggestionsProvider"
|
||||||
|
private const val MODE = DATABASE_MODE_QUERIES
|
||||||
|
|
||||||
|
private val uri = Uri.Builder()
|
||||||
|
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||||
|
.authority(AUTHORITY)
|
||||||
|
.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY)
|
||||||
|
.build()
|
||||||
|
private val projection = arrayOf("_id", SearchManager.SUGGEST_COLUMN_QUERY)
|
||||||
|
|
||||||
|
fun saveQuery(context: Context, query: String) {
|
||||||
|
SearchRecentSuggestions(
|
||||||
|
context,
|
||||||
|
AUTHORITY,
|
||||||
|
MODE
|
||||||
|
).saveRecentQuery(query, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearHistory(context: Context) {
|
||||||
|
SearchRecentSuggestions(
|
||||||
|
context,
|
||||||
|
AUTHORITY,
|
||||||
|
MODE
|
||||||
|
).clearHistory()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCursor(context: Context): Cursor? {
|
||||||
|
return context.contentResolver?.query(uri, projection, null, arrayOf(""), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSuggestionAdapter(context: Context): CursorAdapter? = getCursor(
|
||||||
|
context
|
||||||
|
)?.let { cursor ->
|
||||||
|
SearchSuggestionAdapter(context, cursor).also {
|
||||||
|
it.setFilterQueryProvider { q ->
|
||||||
|
context.contentResolver?.query(uri, projection, " ?", arrayOf(q.toString()), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
package org.koitharu.kotatsu.ui.search
|
package org.koitharu.kotatsu.ui.search
|
||||||
|
|
||||||
import android.app.SearchManager
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Parcelable
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.domain.search.MangaSuggestionsProvider
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.ui.common.BaseActivity
|
import org.koitharu.kotatsu.ui.common.BaseActivity
|
||||||
|
|
||||||
class SearchActivity : BaseActivity() {
|
class SearchActivity : BaseActivity() {
|
||||||
@@ -12,22 +13,31 @@ class SearchActivity : BaseActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_search)
|
setContentView(R.layout.activity_search)
|
||||||
val query = if (Intent.ACTION_SEARCH == intent.action) {
|
val source = intent.getParcelableExtra<MangaSource>(EXTRA_SOURCE)
|
||||||
intent.getStringExtra(SearchManager.QUERY)?.trim()
|
val query = intent.getStringExtra(EXTRA_QUERY)
|
||||||
} else {
|
|
||||||
null
|
if (source == null || query == null) {
|
||||||
}
|
|
||||||
if (query == null) {
|
|
||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
MangaSuggestionsProvider.saveQuery(this, query)
|
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
title = query
|
title = query
|
||||||
supportActionBar?.setSubtitle(R.string.search_results)
|
supportActionBar?.setSubtitle(R.string.search_results)
|
||||||
supportFragmentManager
|
supportFragmentManager
|
||||||
.beginTransaction()
|
.beginTransaction()
|
||||||
.replace(R.id.container, SearchFragment.newInstance(query))
|
.replace(R.id.container, SearchFragment.newInstance(source, query))
|
||||||
.commit()
|
.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val EXTRA_SOURCE = "source"
|
||||||
|
private const val EXTRA_QUERY = "query"
|
||||||
|
|
||||||
|
fun newIntent(context: Context, source: MangaSource, query: String) =
|
||||||
|
Intent(context, SearchActivity::class.java)
|
||||||
|
.putExtra(EXTRA_SOURCE, source as Parcelable)
|
||||||
|
.putExtra(EXTRA_QUERY, query)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.koitharu.kotatsu.ui.search
|
package org.koitharu.kotatsu.ui.search
|
||||||
|
|
||||||
import moxy.ktx.moxyPresenter
|
import moxy.ktx.moxyPresenter
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
|
import org.koitharu.kotatsu.ui.main.list.MangaListFragment
|
||||||
import org.koitharu.kotatsu.utils.ext.withArgs
|
import org.koitharu.kotatsu.utils.ext.withArgs
|
||||||
|
|
||||||
@@ -9,9 +10,10 @@ class SearchFragment : MangaListFragment<Unit>() {
|
|||||||
private val presenter by moxyPresenter(factory = ::SearchPresenter)
|
private val presenter by moxyPresenter(factory = ::SearchPresenter)
|
||||||
|
|
||||||
private val query by stringArg(ARG_QUERY)
|
private val query by stringArg(ARG_QUERY)
|
||||||
|
private val source by arg<MangaSource>(ARG_SOURCE)
|
||||||
|
|
||||||
override fun onRequestMoreItems(offset: Int) {
|
override fun onRequestMoreItems(offset: Int) {
|
||||||
presenter.loadList(query.orEmpty(), offset)
|
presenter.loadList(source, query.orEmpty(), offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTitle(): CharSequence? {
|
override fun getTitle(): CharSequence? {
|
||||||
@@ -21,8 +23,10 @@ class SearchFragment : MangaListFragment<Unit>() {
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val ARG_QUERY = "query"
|
private const val ARG_QUERY = "query"
|
||||||
|
private const val ARG_SOURCE = "source"
|
||||||
|
|
||||||
fun newInstance(query: String) = SearchFragment().withArgs(1) {
|
fun newInstance(source: MangaSource, query: String) = SearchFragment().withArgs(2) {
|
||||||
|
putParcelable(ARG_SOURCE, source)
|
||||||
putString(ARG_QUERY, query)
|
putString(ARG_QUERY, query)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package org.koitharu.kotatsu.ui.search
|
||||||
|
|
||||||
|
import android.app.SearchManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.database.Cursor
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.inputmethod.EditorInfo
|
||||||
|
import androidx.appcompat.widget.SearchView
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.utils.ext.safe
|
||||||
|
|
||||||
|
object SearchHelper {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setupSearchView(menuItem: MenuItem, source: MangaSource) {
|
||||||
|
val view = menuItem.actionView as? SearchView ?: return
|
||||||
|
val context = view.context
|
||||||
|
view.queryHint = context.getString(R.string.search_manga)
|
||||||
|
view.imeOptions = EditorInfo.IME_ACTION_SEARCH
|
||||||
|
view.inputType = EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE
|
||||||
|
view.suggestionsAdapter = MangaSuggestionsProvider.getSuggestionAdapter(context)
|
||||||
|
view.setOnQueryTextListener(QueryListener(context, source))
|
||||||
|
view.setOnSuggestionListener(SuggestionListener(view))
|
||||||
|
}
|
||||||
|
|
||||||
|
private class QueryListener(private val context: Context, private val source: MangaSource) :
|
||||||
|
SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
|
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||||
|
return if (!query.isNullOrBlank()) {
|
||||||
|
context.startActivity(SearchActivity.newIntent(context, source, query.trim()))
|
||||||
|
MangaSuggestionsProvider.saveQuery(context, query)
|
||||||
|
true
|
||||||
|
} else false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextChange(newText: String?) = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SuggestionListener(private val view: SearchView) :
|
||||||
|
SearchView.OnSuggestionListener {
|
||||||
|
|
||||||
|
override fun onSuggestionSelect(position: Int) = false
|
||||||
|
|
||||||
|
override fun onSuggestionClick(position: Int): Boolean {
|
||||||
|
val query = safe {
|
||||||
|
val c = view.suggestionsAdapter.getItem(position) as? Cursor
|
||||||
|
c?.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY))
|
||||||
|
} ?: return false
|
||||||
|
view.setQuery(query, true)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,13 +21,12 @@ class SearchPresenter : BasePresenter<MangaListView<Unit>>() {
|
|||||||
super.onFirstViewAttach()
|
super.onFirstViewAttach()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadList(query: String, offset: Int) {
|
fun loadList(source: MangaSource, query: String, offset: Int) {
|
||||||
presenterScope.launch {
|
presenterScope.launch {
|
||||||
viewState.onLoadingChanged(true)
|
viewState.onLoadingChanged(true)
|
||||||
try {
|
try {
|
||||||
//TODO select source
|
|
||||||
val list = withContext(Dispatchers.IO) {
|
val list = withContext(Dispatchers.IO) {
|
||||||
MangaProviderFactory.create(MangaSource.READMANGA_RU)
|
MangaProviderFactory.create(source)
|
||||||
.getList(offset, query = query)
|
.getList(offset, query = query)
|
||||||
}
|
}
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.utils
|
|
||||||
|
|
||||||
import android.app.SearchManager
|
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.view.MenuItem
|
|
||||||
import androidx.appcompat.widget.SearchView
|
|
||||||
import org.koitharu.kotatsu.ui.search.SearchActivity
|
|
||||||
|
|
||||||
object SearchHelper {
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
fun setupSearchView(menuItem: MenuItem) {
|
|
||||||
val view = menuItem.actionView as? SearchView ?: return
|
|
||||||
val context = view.context
|
|
||||||
val searchManager = context.applicationContext.getSystemService(Context.SEARCH_SERVICE) as SearchManager
|
|
||||||
val info = searchManager.getSearchableInfo(ComponentName(context, SearchActivity::class.java))
|
|
||||||
view.setSearchableInfo(info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?colorPrimary"
|
android:background="?colorPrimary"
|
||||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
android:theme="@style/AppToolbarTheme">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@id/toolbar"
|
android:id="@id/toolbar"
|
||||||
|
|||||||
@@ -18,14 +18,13 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?colorPrimary"
|
android:background="?colorPrimary"
|
||||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
android:theme="@style/AppToolbarTheme">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@id/toolbar"
|
android:id="@id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_scrollFlags="scroll|enterAlways"
|
app:layout_scrollFlags="scroll|enterAlways" />
|
||||||
app:popupTheme="@style/AppPopupTheme" />
|
|
||||||
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
android:background="@color/dim"
|
android:background="@color/dim"
|
||||||
android:elevation="0dp"
|
android:elevation="0dp"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
|
android:theme="@style/AppToolbarTheme"
|
||||||
app:elevation="0dp">
|
app:elevation="0dp">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
android:background="@color/dim"
|
android:background="@color/dim"
|
||||||
android:elevation="0dp"
|
android:elevation="0dp"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
|
android:theme="@style/AppToolbarTheme"
|
||||||
app:elevation="0dp">
|
app:elevation="0dp">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:background="?colorPrimary"
|
android:background="?colorPrimary"
|
||||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
android:theme="@style/AppToolbarTheme">
|
||||||
|
|
||||||
<androidx.appcompat.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@id/toolbar"
|
android:id="@id/toolbar"
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?colorPrimary"
|
android:background="?colorPrimary"
|
||||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
|
android:theme="@style/AppToolbarTheme">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@id/toolbar"
|
android:id="@id/toolbar"
|
||||||
|
|||||||
16
app/src/main/res/layout/item_search_complete.xml
Normal file
16
app/src/main/res/layout/item_search_complete.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TextView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?listPreferredItemHeightSmall"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
android:drawableStart="@drawable/ic_history"
|
||||||
|
android:drawablePadding="20dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="?listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?listPreferredItemPaddingEnd"
|
||||||
|
android:textAppearance="?textAppearanceListItemSmall"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:theme="@style/AppPopupTheme"
|
||||||
|
tools:text="@tools:sample/full_names" />
|
||||||
@@ -3,12 +3,6 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_search"
|
|
||||||
android:icon="@drawable/ic_search"
|
|
||||||
android:orderInCategory="0"
|
|
||||||
android:title="@string/search"
|
|
||||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
|
||||||
app:showAsAction="ifRoom|collapseActionView" />
|
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
14
app/src/main/res/menu/opt_remote.xml
Normal file
14
app/src/main/res/menu/opt_remote.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?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">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_search"
|
||||||
|
android:icon="@drawable/ic_search"
|
||||||
|
android:orderInCategory="1"
|
||||||
|
android:title="@string/search"
|
||||||
|
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||||
|
app:showAsAction="always|collapseActionView" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<style name="AppPopupTheme" parent="ThemeOverlay.MaterialComponents.Dark" />
|
<style name="AppPopupTheme" parent="ThemeOverlay.MaterialComponents.Dark" />
|
||||||
|
|
||||||
|
<style name="AppSuggestion" parent="Widget.AppCompat.AutoCompleteTextView">
|
||||||
|
<item name="android:popupBackground">@android:color/background_dark</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -10,4 +10,13 @@
|
|||||||
|
|
||||||
<style name="AppPopupTheme" parent="ThemeOverlay.MaterialComponents.Light" />
|
<style name="AppPopupTheme" parent="ThemeOverlay.MaterialComponents.Light" />
|
||||||
|
|
||||||
|
<style name="AppToolbarTheme" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar" >
|
||||||
|
<item name="popupTheme">@style/AppPopupTheme</item>
|
||||||
|
<item name="autoCompleteTextViewStyle">@style/AppSuggestion</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="AppSuggestion" parent="Widget.AppCompat.Light.AutoCompleteTextView">
|
||||||
|
<item name="android:popupBackground">@android:color/background_light</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<searchable
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:hint="@string/search_manga"
|
|
||||||
android:inputType="textPersonName"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:searchSuggestAuthority="org.koitharu.kotatsu.MangaSuggestionsProvider"
|
|
||||||
android:searchSuggestSelection=" ?"
|
|
||||||
android:voiceLanguageModel="web_search"
|
|
||||||
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" />
|
|
||||||
Reference in New Issue
Block a user