Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Shows and hides keyboard when scrolling the app drawer #162

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
android:screenOrientation="portrait"
android:stateNotNeeded="true"
tools:ignore="LockedOrientationActivity"
android:windowSoftInputMode="adjustNothing"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
56 changes: 46 additions & 10 deletions app/src/main/java/com/sduduzog/slimlauncher/ui/main/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import android.content.*
import android.content.pm.LauncherApps
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.UserManager
import android.provider.AlarmClock
import android.provider.CalendarContract
import android.provider.MediaStore
import android.provider.Settings
import android.util.Log
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
Expand All @@ -20,6 +23,9 @@ import android.widget.PopupMenu
import android.widget.Toast
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.constraintlayout.motion.widget.MotionLayout.TransitionListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsAnimationCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.Navigation
Expand All @@ -34,8 +40,11 @@ import com.sduduzog.slimlauncher.datasource.quickbuttonprefs.QuickButtonPreferen
import com.sduduzog.slimlauncher.models.HomeApp
import com.sduduzog.slimlauncher.models.MainViewModel
import com.sduduzog.slimlauncher.ui.dialogs.RenameAppDisplayNameDialog
import com.sduduzog.slimlauncher.utils.AppDrawerScrollListener
import com.sduduzog.slimlauncher.utils.BaseFragment
import com.sduduzog.slimlauncher.utils.OnLaunchAppListener
import com.sduduzog.slimlauncher.utils.isKeyboardOpen
import com.sduduzog.slimlauncher.utils.shouldOpenKeyboard
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.android.synthetic.main.home_fragment_default.*
import kotlinx.android.synthetic.main.home_fragment_content.*
Expand All @@ -55,6 +64,12 @@ class HomeFragment : BaseFragment(), OnLaunchAppListener {

private lateinit var receiver: BroadcastReceiver
private lateinit var appDrawerAdapter: AppDrawerAdapter
private lateinit var inputMethodManager: InputMethodManager

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
inputMethodManager = requireContext().getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val coreRepository = unlauncherDataSource.corePreferencesRepo
Expand Down Expand Up @@ -221,9 +236,8 @@ class HomeFragment : BaseFragment(), OnLaunchAppListener {
}

home_fragment.setTransitionListener(object : TransitionListener {
val handler = Handler(Looper.getMainLooper())
override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
val inputMethodManager = requireContext().getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager

when (currentId) {
motionLayout?.startState -> {
// hide the keyboard and remove focus from the EditText when swiping back up
Expand All @@ -237,14 +251,17 @@ class HomeFragment : BaseFragment(), OnLaunchAppListener {
val activateKeyboard = repository.get().activateKeyboardInDrawer

// Check for preferences to open the keyboard
// only if the search field is shown
if (showSearchField && activateKeyboard) {
app_drawer_edit_text.requestFocus()
// show the keyboard and set focus to the EditText when swiping down
inputMethodManager.showSoftInput(
app_drawer_edit_text,
InputMethodManager.SHOW_IMPLICIT
)
if (shouldOpenKeyboard(unlauncherDataSource)) {
// in order to avoid UI Jank, we add the focus and showing the keyboard
// in the back of the queue
handler.post {
app_drawer_edit_text.requestFocus()
// show the keyboard and set focus to the EditText when swiping down
inputMethodManager.showSoftInput(
app_drawer_edit_text,
InputMethodManager.SHOW_IMPLICIT
)
}
}
}
}
Expand All @@ -262,6 +279,25 @@ class HomeFragment : BaseFragment(), OnLaunchAppListener {
// do nothing
}
})

app_drawer_fragment_list.addOnScrollListener(object: AppDrawerScrollListener() {
override fun onScrolledUp() {
if (shouldOpenKeyboard(unlauncherDataSource) && !isKeyboardOpen(app_drawer_edit_text)) {
// show the keyboard again when user is scrolling up
inputMethodManager.showSoftInput(
app_drawer_edit_text,
InputMethodManager.SHOW_IMPLICIT
)
}
}

override fun onScrolledDown() {
if (shouldOpenKeyboard(unlauncherDataSource) && isKeyboardOpen(app_drawer_edit_text)) {
// hide the keyboard again when scrolling down
inputMethodManager.hideSoftInputFromWindow(requireView().windowToken, 0)
}
}
})
}

fun updateClock() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.sduduzog.slimlauncher.utils

import androidx.recyclerview.widget.RecyclerView

abstract class AppDrawerScrollListener : RecyclerView.OnScrollListener() {

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (recyclerView.scrollState == RecyclerView.SCROLL_STATE_DRAGGING) {
if (dy > 0) {
// finger moves upwards
onScrolledDown()
} else if (dy < 0) {
// finger moves downwards
onScrolledUp()
}
}
}

/**
* Called when user is scrolling upward the [RecyclerView]
*/
abstract fun onScrolledUp()

/**
* * Called when user is scrolling downward the [RecyclerView]
*/
abstract fun onScrolledDown()


}
17 changes: 17 additions & 0 deletions app/src/main/java/com/sduduzog/slimlauncher/utils/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.TextAppearanceSpan
import android.util.DisplayMetrics
import android.util.Log
import android.view.View
import android.view.WindowInsets
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.sduduzog.slimlauncher.datasource.UnlauncherDataSource
import androidx.annotation.StringRes
import com.sduduzog.slimlauncher.R

Expand Down Expand Up @@ -77,6 +82,18 @@ fun getScreenHeight(activity: Activity): Int {
}
}

fun shouldOpenKeyboard(unlauncherDataSource: UnlauncherDataSource) : Boolean =
unlauncherDataSource.corePreferencesRepo.get().activateKeyboardInDrawer

/**
* @return [true] when the keyboard is displayed.
* Works for android API [20] and higher
*/
fun isKeyboardOpen(view: View) : Boolean {
val insets = ViewCompat.getRootWindowInsets(view)
return insets?.isVisible(WindowInsetsCompat.Type.ime()) ?: false
}

fun createTitleAndSubtitleText(context: Context, @StringRes titleRes: Int, @StringRes subtitleRes: Int) : CharSequence
= createTitleAndSubtitleText(context, context.getString(titleRes), context.getString(subtitleRes))

Expand Down