Added a placeholder for search in custom apps.

* Introduced a search placeholder for custom apps; if any custom app is configured not to show the title in the toolbar, it will display the search placeholder with a border. To implement this change, a layout has been added inside the toolbar.
* To enhance understanding of this change, proper comments have been added to the methods.
This commit is contained in:
MohitMaliFtechiz 2023-12-04 19:32:20 +05:30
parent 88475d8601
commit bbcf8bea8c
7 changed files with 102 additions and 15 deletions

View File

@ -55,7 +55,8 @@ abstract class ActivityModule {
urlIsValid: Boolean, urlIsValid: Boolean,
menuClickListener: MenuClickListener, menuClickListener: MenuClickListener,
disableReadAloud: Boolean, disableReadAloud: Boolean,
disableTabs: Boolean disableTabs: Boolean,
disableSearch: Boolean
): MainMenu = MainMenu( ): MainMenu = MainMenu(
activity, activity,
zimReaderContainer.zimFileReader, zimReaderContainer.zimFileReader,
@ -64,6 +65,7 @@ abstract class ActivityModule {
urlIsValid, urlIsValid,
disableReadAloud, disableReadAloud,
disableTabs, disableTabs,
disableSearch,
menuClickListener menuClickListener
) )
} }

View File

@ -48,6 +48,7 @@ import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.View.VISIBLE
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.AnimationUtils import android.view.animation.AnimationUtils
import android.webkit.WebBackForwardList import android.webkit.WebBackForwardList
@ -519,6 +520,9 @@ abstract class CoreReaderFragment :
viewLifecycleOwner, viewLifecycleOwner,
Observer(::openSearchItem) Observer(::openSearchItem)
) )
toolbarWithSearchPlaceholder?.setOnClickListener {
openSearch(searchString = "", isOpenedFromTabView = false, false)
}
} }
private fun initTabCallback() { private fun initTabCallback() {
@ -719,7 +723,7 @@ abstract class CoreReaderFragment :
contentFrame?.visibility = View.GONE contentFrame?.visibility = View.GONE
progressBar?.visibility = View.GONE progressBar?.visibility = View.GONE
backToTopButton?.hide() backToTopButton?.hide()
tabSwitcherRoot?.visibility = View.VISIBLE setTabSwitcherVisibility(VISIBLE)
startAnimation(tabSwitcherRoot, R.anim.slide_down) startAnimation(tabSwitcherRoot, R.anim.slide_down)
tabsAdapter?.let { tabsAdapter -> tabsAdapter?.let { tabsAdapter ->
tabRecyclerView?.let { recyclerView -> tabRecyclerView?.let { recyclerView ->
@ -737,6 +741,19 @@ abstract class CoreReaderFragment :
mainMenu?.showTabSwitcherOptions() mainMenu?.showTabSwitcherOptions()
} }
/**
* Sets the tabs switcher visibility, controlling the visibility of the tab.
* Subclasses, like CustomReaderFragment, override this method to provide custom
* behavior, such as hiding the placeholder in the toolbar when a custom app is configured
* not to show the title. This is necessary because the same toolbar is used for displaying tabs.
*
* WARNING: If modifying this method, ensure thorough testing with custom apps
* to verify proper functionality.
*/
open fun setTabSwitcherVisibility(visibility: Int) {
tabSwitcherRoot?.visibility = visibility
}
/** /**
* Sets a top margin to the web views. * Sets a top margin to the web views.
* *
@ -775,7 +792,7 @@ abstract class CoreReaderFragment :
) )
tabSwitcherRoot?.let { tabSwitcherRoot?.let {
if (it.visibility == View.VISIBLE) { if (it.visibility == View.VISIBLE) {
it.visibility = View.GONE setTabSwitcherVisibility(View.GONE)
startAnimation(it, R.anim.slide_up) startAnimation(it, R.anim.slide_up)
progressBar?.visibility = View.VISIBLE progressBar?.visibility = View.VISIBLE
contentFrame?.visibility = View.VISIBLE contentFrame?.visibility = View.VISIBLE

View File

@ -28,6 +28,7 @@ import org.kiwix.kiwixmobile.core.reader.ZimFileReader
const val REQUEST_FILE_SEARCH = 1236 const val REQUEST_FILE_SEARCH = 1236
@Suppress("LongParameterList")
class MainMenu( class MainMenu(
private val activity: Activity, private val activity: Activity,
zimFileReader: ZimFileReader?, zimFileReader: ZimFileReader?,
@ -36,6 +37,7 @@ class MainMenu(
urlIsValid: Boolean, urlIsValid: Boolean,
disableReadAloud: Boolean = false, disableReadAloud: Boolean = false,
disableTabs: Boolean = false, disableTabs: Boolean = false,
private val disableSearch: Boolean = false,
private val menuClickListener: MenuClickListener private val menuClickListener: MenuClickListener
) { ) {
@ -46,7 +48,8 @@ class MainMenu(
urlIsValid: Boolean, urlIsValid: Boolean,
menuClickListener: MenuClickListener, menuClickListener: MenuClickListener,
disableReadAloud: Boolean, disableReadAloud: Boolean,
disableTabs: Boolean disableTabs: Boolean,
disableSearch: Boolean = false
): MainMenu ): MainMenu
} }
@ -85,6 +88,10 @@ class MainMenu(
tabSwitcherTextView = null tabSwitcherTextView = null
} }
if (disableSearch) {
search?.isVisible = false
}
randomArticle.setShowAsAction( randomArticle.setShowAsAction(
if (activity.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) if (activity.resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
MenuItem.SHOW_AS_ACTION_IF_ROOM MenuItem.SHOW_AS_ACTION_IF_ROOM
@ -155,7 +162,13 @@ class MainMenu(
} }
private fun setVisibility(visibility: Boolean, vararg menuItems: MenuItem?) { private fun setVisibility(visibility: Boolean, vararg menuItems: MenuItem?) {
menuItems.forEach { it?.isVisible = visibility } menuItems.forEach {
if (it == search && disableSearch) {
it?.isVisible = false
} else {
it?.isVisible = visibility
}
}
} }
fun tryExpandSearch(zimFileReader: ZimFileReader?) { fun tryExpandSearch(zimFileReader: ZimFileReader?) {

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="3dip" />
<stroke
android:width="1.5dip"
android:color="@color/alabaster_white" />
<padding
android:bottom="0dip"
android:left="0dip"
android:right="0dip"
android:top="0dip" />
</shape>

View File

@ -1,13 +1,34 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<merge> <merge xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" <androidx.appcompat.widget.Toolbar 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" xmlns:tools="http://schemas.android.com/tools"
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:popupTheme="@style/KiwixTheme" app:popupTheme="@style/KiwixTheme"
app:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" app:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
tools:showIn="@layout/fragment_search" /> tools:showIn="@layout/fragment_search">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/toolbarWithSearchPlaceholder"
android:layout_width="match_parent"
android:visibility="gone"
android:background="@drawable/search_placeholder_background"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/search_label"
android:padding="5dip"
android:layout_marginStart="5dip"
app:layout_constraintTop_toTopOf="parent"
android:gravity="center_vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:drawableRightCompat="@drawable/action_search"
android:drawablePadding="10dip" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
</merge> </merge>

View File

@ -8,7 +8,8 @@
android:title="@string/search_label" android:title="@string/search_label"
android:visible="false" android:visible="false"
app:showAsAction="always" app:showAsAction="always"
tools:visible="true" /> tools:visible="true"
tools:ignore="AlwaysShowAction" />
<item <item
android:id="@+id/menu_tab_switcher" android:id="@+id/menu_tab_switcher"
@ -21,7 +22,7 @@
android:icon="@drawable/ic_add_note" android:icon="@drawable/ic_add_note"
android:title="@string/note" android:title="@string/note"
android:visible="false" android:visible="false"
app:showAsAction="ifRoom" /> app:showAsAction="never" />
<item <item

View File

@ -88,6 +88,7 @@ class CustomReaderFragment : CoreReaderFragment() {
* in a custom app, this function set the app logo on hamburger. * in a custom app, this function set the app logo on hamburger.
*/ */
override fun setUpDrawerToggle(toolbar: Toolbar) { override fun setUpDrawerToggle(toolbar: Toolbar) {
super.setUpDrawerToggle(toolbar)
if (BuildConfig.DISABLE_TITLE) { if (BuildConfig.DISABLE_TITLE) {
// if the title is disable then set the app logo to hamburger icon, // if the title is disable then set the app logo to hamburger icon,
// see https://github.com/kiwix/kiwix-android/issues/3528#issuecomment-1814905330 // see https://github.com/kiwix/kiwix-android/issues/3528#issuecomment-1814905330
@ -95,13 +96,29 @@ class CustomReaderFragment : CoreReaderFragment() {
resources.getDimensionPixelSize(dimen.hamburger_icon_size) resources.getDimensionPixelSize(dimen.hamburger_icon_size)
requireActivity().getResizedDrawable(R.mipmap.ic_launcher, iconSize, iconSize) requireActivity().getResizedDrawable(R.mipmap.ic_launcher, iconSize, iconSize)
?.let { drawable -> ?.let { drawable ->
toolbar.navigationIcon = drawable super.toolbar?.navigationIcon = drawable
} }
} else {
super.setUpDrawerToggle(toolbar)
} }
} }
/**
* Overrides the method to hide/show the placeholder from toolbar.
* When the "setting title" is disabled/enabled in a custom app,
* this function set the visibility of placeholder in toolbar when showing the tabs.
*/
override fun setTabSwitcherVisibility(visibility: Int) {
if (BuildConfig.DISABLE_TITLE) {
// If custom apps are configured to show the placeholder,
// and if tabs are visible, hide the placeholder.
// If tabs are hidden, show the placeholder.
updateToolbarSearchPlaceholderVisibility(if (visibility == VISIBLE) GONE else VISIBLE)
} else {
// Permanently hide the placeholder if the custom app is not configured to show it.
updateToolbarSearchPlaceholderVisibility(GONE)
}
super.setTabSwitcherVisibility(visibility)
}
private fun loadPageFromNavigationArguments() { private fun loadPageFromNavigationArguments() {
val args = CustomReaderFragmentArgs.fromBundle(requireArguments()) val args = CustomReaderFragmentArgs.fromBundle(requireArguments())
if (args.pageUrl.isNotEmpty()) { if (args.pageUrl.isNotEmpty()) {
@ -277,13 +294,17 @@ class CustomReaderFragment : CoreReaderFragment() {
// even if it is empty. If we do not set up this title, // even if it is empty. If we do not set up this title,
// the search screen will open if the user clicks on the toolbar from the tabs screen. // the search screen will open if the user clicks on the toolbar from the tabs screen.
actionBar?.title = " " actionBar?.title = " "
toolbarWithSearchPlaceholder?.visibility = VISIBLE updateToolbarSearchPlaceholderVisibility(VISIBLE)
} else { } else {
toolbarWithSearchPlaceholder?.visibility = GONE updateToolbarSearchPlaceholderVisibility(GONE)
super.updateTitle() super.updateTitle()
} }
} }
private fun updateToolbarSearchPlaceholderVisibility(visibility: Int) {
toolbarWithSearchPlaceholder?.visibility = visibility
}
override fun createNewTab() { override fun createNewTab() {
newMainPageTab() newMainPageTab()
} }