diff options
| author | Dirk Sierd de Vries <contact@lecapuchon.nl> | 2026-08-09 19:19:49 +0200 |
|---|---|---|
| committer | Dirk Sierd de Vries <contact@lecapuchon.nl> | 2026-08-09 19:19:49 +0200 |
| commit | 7971690ac82fc5a0f3e547a8c2f3f1acfa5608ab (patch) | |
| tree | 84201ee351cd7e623b2375780873dcc86aaeeda7 /app/src/main | |
| parent | 3dc9370c4ea3319f027bcb6be137c000c523d497 (diff) | |
| download | SidePhOnelauncher-7971690ac82fc5a0f3e547a8c2f3f1acfa5608ab.tar.gz SidePhOnelauncher-7971690ac82fc5a0f3e547a8c2f3f1acfa5608ab.tar.bz2 SidePhOnelauncher-7971690ac82fc5a0f3e547a8c2f3f1acfa5608ab.zip | |
Add D-pad navigation and keypad-friendly app search
Diffstat (limited to 'app/src/main')
| -rw-r--r-- | app/src/main/java/app/olauncher/MainActivity.kt | 24 | ||||
| -rw-r--r-- | app/src/main/java/app/olauncher/listener/ViewSwipeTouchListener.kt | 8 | ||||
| -rw-r--r-- | app/src/main/java/app/olauncher/ui/AppDrawerAdapter.kt | 36 | ||||
| -rw-r--r-- | app/src/main/java/app/olauncher/ui/AppDrawerFragment.kt | 72 | ||||
| -rw-r--r-- | app/src/main/java/app/olauncher/ui/HomeFragment.kt | 214 | ||||
| -rw-r--r-- | app/src/main/res/layout/adapter_app_drawer.xml | 23 | ||||
| -rw-r--r-- | app/src/main/res/layout/fragment_app_drawer.xml | 2 | ||||
| -rw-r--r-- | app/src/main/res/layout/fragment_home.xml | 16 |
8 files changed, 339 insertions, 56 deletions
diff --git a/app/src/main/java/app/olauncher/MainActivity.kt b/app/src/main/java/app/olauncher/MainActivity.kt index 27a66b9..ebd05d5 100644 --- a/app/src/main/java/app/olauncher/MainActivity.kt +++ b/app/src/main/java/app/olauncher/MainActivity.kt @@ -11,6 +11,7 @@ import android.content.res.Configuration import android.os.Build import android.os.Bundle import android.provider.Settings +import android.view.KeyEvent import android.view.View import android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS import androidx.activity.OnBackPressedCallback @@ -74,6 +75,7 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) + setDefaultKeyMode(Activity.DEFAULT_KEYS_DISABLE) navController = this.findNavController(R.id.nav_host_fragment) viewModel = ViewModelProvider(this)[MainViewModel::class.java] @@ -124,6 +126,28 @@ class MainActivity : AppCompatActivity() { } } + override fun dispatchKeyEvent(event: KeyEvent): Boolean { + val dpadKey = when (event.keyCode) { + KeyEvent.KEYCODE_DPAD_UP, + KeyEvent.KEYCODE_DPAD_DOWN, + KeyEvent.KEYCODE_DPAD_LEFT, + KeyEvent.KEYCODE_DPAD_RIGHT, + KeyEvent.KEYCODE_DPAD_CENTER, + KeyEvent.KEYCODE_ENTER -> true + else -> false + } + if (dpadKey) { + val focusedView = currentFocus + if (focusedView == null || focusedView == window.decorView) { + val navHost = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) + val currentFragment = navHost?.childFragmentManager?.fragments?.firstOrNull() + val fragmentView = currentFragment?.view + if (fragmentView != null && fragmentView.dispatchKeyEvent(event)) return true + } + } + return super.dispatchKeyEvent(event) + } + override fun onStart() { super.onStart() restartLauncherOrCheckTheme() diff --git a/app/src/main/java/app/olauncher/listener/ViewSwipeTouchListener.kt b/app/src/main/java/app/olauncher/listener/ViewSwipeTouchListener.kt index 9d7009e..633b779 100644 --- a/app/src/main/java/app/olauncher/listener/ViewSwipeTouchListener.kt +++ b/app/src/main/java/app/olauncher/listener/ViewSwipeTouchListener.kt @@ -22,7 +22,7 @@ internal open class ViewSwipeTouchListener(c: Context?, v: View) : OnTouchListen override fun onTouch(view: View, motionEvent: MotionEvent): Boolean { when (motionEvent.action) { MotionEvent.ACTION_DOWN -> view.isPressed = true - MotionEvent.ACTION_UP -> view.isPressed = false + MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> view.isPressed = false } return gestureDetector.onTouchEvent(motionEvent) } @@ -36,8 +36,8 @@ internal open class ViewSwipeTouchListener(c: Context?, v: View) : OnTouchListen } override fun onSingleTapUp(e: MotionEvent): Boolean { - onClick(view) - return super.onSingleTapUp(e) + view.performClick() + return true } override fun onDoubleTap(e: MotionEvent): Boolean { @@ -51,7 +51,7 @@ internal open class ViewSwipeTouchListener(c: Context?, v: View) : OnTouchListen delay(Constants.LONG_PRESS_DELAY_MS) withContext(Dispatchers.Main) { if (isActive && longPressOn) - onLongClick(view) + view.performLongClick() } } super.onLongPress(e) diff --git a/app/src/main/java/app/olauncher/ui/AppDrawerAdapter.kt b/app/src/main/java/app/olauncher/ui/AppDrawerAdapter.kt index 7d519f8..07428b5 100644 --- a/app/src/main/java/app/olauncher/ui/AppDrawerAdapter.kt +++ b/app/src/main/java/app/olauncher/ui/AppDrawerAdapter.kt @@ -5,6 +5,7 @@ import android.content.pm.LauncherApps import android.os.UserHandle import android.text.Editable import android.text.TextWatcher +import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -86,7 +87,6 @@ class AppDrawerAdapter( false ) ) - else -> ViewHolder( AdapterAppDrawerBinding.inflate( LayoutInflater.from(parent.context), @@ -109,7 +109,6 @@ class AppDrawerAdapter( privateSpaceSettingsListener, ) } - is ViewHolder -> holder.bind( flag, appLabelGravity, @@ -184,7 +183,6 @@ class AppDrawerAdapter( .replace(separatorsRegex, "") fun setAppList(appsList: MutableList<AppModel>) { - // Add empty app for bottom padding in recyclerview and assign to list appsList.add( AppModel.App( appLabel = "", @@ -238,7 +236,6 @@ class AppDrawerAdapter( renameLayout.visibility = View.GONE appTitle.visibility = View.VISIBLE - // Show indicators in title based on app type and state appTitle.text = buildString { append(appModel.appLabel) if (appModel.isNew) append(" ✦") @@ -246,9 +243,8 @@ class AppDrawerAdapter( appTitle.gravity = appLabelGravity otherProfileIndicator.isVisible = appModel.user != myUserHandle - appTitle.setOnClickListener { clickListener(appModel) } - - appTitle.setOnLongClickListener { + appRow.setOnClickListener { clickListener(appModel) } + appRow.setOnLongClickListener { if (appModel.appPackage.isNotEmpty()) { appDelete.alpha = when ( appModel is AppModel.PinnedShortcut || !root.context.isSystemApp(appModel.appPackage, appModel.user) @@ -266,13 +262,33 @@ class AppDrawerAdapter( false -> 1.0f } appHideLayout.visibility = View.VISIBLE - // Only allow renaming non hidden apps appRename.isVisible = flag != Constants.FLAG_HIDDEN_APPS } true } + appRow.setOnKeyListener { _, keyCode, event -> + when (keyCode) { + KeyEvent.KEYCODE_ENTER, + KeyEvent.KEYCODE_DPAD_CENTER, + KeyEvent.KEYCODE_NUMPAD_ENTER -> { + when (event.action) { + KeyEvent.ACTION_DOWN -> { + if (event.repeatCount > 0) { + appRow.performLongClick() + } + true + } + KeyEvent.ACTION_UP -> { + if (event.repeatCount == 0) appRow.performClick() + true + } + else -> false + } + } + else -> false + } + } - // Configure rename behavior appRename.setOnClickListener { if (appModel.appPackage.isNotEmpty()) { etAppRename.hint = getAppName(etAppRename.context, appModel.appPackage, appModel.user) @@ -355,7 +371,7 @@ class AppDrawerAdapter( ).toString() } } catch (_: Exception) { - "" // As a fallback, display an empty string. + "" } } } diff --git a/app/src/main/java/app/olauncher/ui/AppDrawerFragment.kt b/app/src/main/java/app/olauncher/ui/AppDrawerFragment.kt index c2cee1c..b4b7ef1 100644 --- a/app/src/main/java/app/olauncher/ui/AppDrawerFragment.kt +++ b/app/src/main/java/app/olauncher/ui/AppDrawerFragment.kt @@ -4,12 +4,15 @@ import android.content.Context import android.os.Build import android.os.Bundle import android.os.Process +import android.text.InputType import android.text.Spannable +import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.animation.AnimationUtils import android.view.inputmethod.BaseInputConnection +import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputMethodManager import android.widget.TextView import androidx.appcompat.widget.SearchView @@ -77,6 +80,41 @@ class AppDrawerFragment : Fragment() { initAdapter() initObservers() initClickListeners() + initKeyNavigation() + } + + private fun initKeyNavigation() { + binding.recyclerView.setOnKeyListener { _, keyCode, event -> + if (event.action != KeyEvent.ACTION_DOWN) return@setOnKeyListener false + when (keyCode) { + KeyEvent.KEYCODE_DPAD_UP -> { + if (!binding.recyclerView.canScrollVertically(-1)) { + val firstVisible = (binding.recyclerView.layoutManager as? LinearLayoutManager) + ?.findFirstVisibleItemPosition() ?: -1 + if (firstVisible <= 0) { + binding.search.requestFocus() + return@setOnKeyListener true + } + } + false + } + KeyEvent.KEYCODE_DEL -> { + val query = binding.search.query + if (query.isNullOrEmpty()) { + findNavController().popBackStack() + true + } else false + } + else -> false + } + } + + binding.search.setOnKeyListener { _, keyCode, event -> + if (event.action != KeyEvent.ACTION_DOWN) return@setOnKeyListener false + if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) { + focusFirstLaunchableItem() + } else false + } } private fun initViews() { @@ -87,6 +125,10 @@ class AppDrawerFragment : Fragment() { try { searchTextView = binding.search.findViewById(R.id.search_src_text) searchTextView?.gravity = prefs.appLabelAlignment + searchTextView?.inputType = + InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD + searchTextView?.imeOptions = + EditorInfo.IME_ACTION_SEARCH or EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING } catch (e: Exception) { e.printStackTrace() } @@ -135,8 +177,8 @@ class AppDrawerFragment : Fragment() { val subtype = imm.currentInputMethodSubtype val language = when { subtype == null -> "" - subtype.languageTag.isNotEmpty() -> subtype.languageTag // e.g. "zh-CN", "ja-JP", "en-US" - else -> subtype.locale // deprecated fallback, e.g. "zh_CN" + subtype.languageTag.isNotEmpty() -> subtype.languageTag + else -> subtype.locale } language.startsWith("zh") || language.startsWith("ja") || language.startsWith("ko") } catch (e: Exception) { @@ -260,8 +302,7 @@ class AppDrawerFragment : Fragment() { } private fun initObservers() { - viewModel.firstOpen.observe(viewLifecycleOwner) { - } + viewModel.firstOpen.observe(viewLifecycleOwner) {} if (flag == Constants.FLAG_HIDDEN_APPS) { viewModel.hiddenApps.observe(viewLifecycleOwner) { it?.let { @@ -305,6 +346,26 @@ class AppDrawerFragment : Fragment() { adapter.filter.filter(binding.search.query) } + private fun findFirstLaunchablePosition(): Int { + return adapter.appFilteredList.indexOfFirst { appModel -> + appModel !is AppModel.PrivateSpaceHeader && appModel.appPackage.isNotBlank() + }.takeIf { it >= 0 } ?: RecyclerView.NO_POSITION + } + + private fun focusFirstLaunchableItem(): Boolean { + val position = findFirstLaunchablePosition() + if (position == RecyclerView.NO_POSITION) return false + + binding.recyclerView.requestFocus() + binding.recyclerView.scrollToPosition(position) + binding.recyclerView.post { + val holder = binding.recyclerView.findViewHolderForAdapterPosition(position) + val itemView = holder?.itemView?.findViewById<View>(R.id.appRow) ?: holder?.itemView + itemView?.requestFocus() + } + return true + } + private fun initClickListeners() { binding.appRename.setOnClickListener { val name = binding.search.query.toString().trim() @@ -330,19 +391,16 @@ class AppDrawerFragment : Fragment() { private fun getRecyclerViewOnScrollListener(): RecyclerView.OnScrollListener { return object : RecyclerView.OnScrollListener() { - var onTop = false override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) when (newState) { - RecyclerView.SCROLL_STATE_DRAGGING -> { onTop = !recyclerView.canScrollVertically(-1) if (onTop) binding.search.hideKeyboard() } - RecyclerView.SCROLL_STATE_IDLE -> { if (!recyclerView.canScrollVertically(1)) binding.search.hideKeyboard() diff --git a/app/src/main/java/app/olauncher/ui/HomeFragment.kt b/app/src/main/java/app/olauncher/ui/HomeFragment.kt index 80061c3..535002c 100644 --- a/app/src/main/java/app/olauncher/ui/HomeFragment.kt +++ b/app/src/main/java/app/olauncher/ui/HomeFragment.kt @@ -9,6 +9,7 @@ import android.os.BatteryManager import android.os.Build import android.os.Bundle import android.view.Gravity +import android.view.KeyEvent import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -59,6 +60,9 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener private var _binding: FragmentHomeBinding? = null private val binding get() = _binding!! + private var dpadLeftKeyDownTime = 0L + private var dpadRightKeyDownTime = 0L + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { _binding = FragmentHomeBinding.inflate(inflater, container, false) return binding.root @@ -77,28 +81,29 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener setHomeAlignment(prefs.homeAlignment) initSwipeTouchListener() initClickListeners() + initKeyNavigation() } override fun onResume() { super.onResume() + dpadLeftKeyDownTime = 0L + dpadRightKeyDownTime = 0L populateHomeScreen(false) viewModel.isOlauncherDefault() if (prefs.showStatusBar) showStatusBar() else hideStatusBar() + requestInitialFocus() } override fun onClick(view: View) { when (view.id) { R.id.lock -> {} - // Home button for recents feature disabled - // R.id.recents -> {} R.id.clock -> openClockApp() R.id.date -> openCalendarApp() R.id.setDefaultLauncher -> viewModel.resetLauncherLiveData.call() R.id.tvScreenTime -> openScreenTimeDigitalWellbeing() - else -> { - try { // Launch app + try { val appLocation = view.tag.toString().toInt() homeAppClicked(appLocation) } catch (e: Exception) { @@ -148,21 +153,18 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener prefs.clockAppClassName = "" prefs.clockAppUser = "" } - R.id.date -> { showAppList(Constants.FLAG_SET_CALENDAR_APP) prefs.calendarAppPackage = "" prefs.calendarAppClassName = "" prefs.calendarAppUser = "" } - R.id.tvScreenTime -> { showAppList(Constants.FLAG_SET_SCREEN_TIME_APP) prefs.screenTimeAppPackage = "" prefs.screenTimeAppClassName = "" prefs.screenTimeAppUser = "" } - R.id.setDefaultLauncher -> { prefs.hideSetDefaultLauncher = true binding.setDefaultLauncher.visibility = View.GONE @@ -205,10 +207,105 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener viewModel.screenTimeValue.observe(viewLifecycleOwner) { it?.let { binding.tvScreenTime.text = it } } - // Home button for recents feature disabled - // viewModel.showRecentApps.observe(viewLifecycleOwner) { - // binding.recents.performClick() - // } + } + + private fun initKeyNavigation() { + binding.mainLayout.isFocusable = true + binding.mainLayout.setOnKeyListener { _, keyCode, event -> + handleHomeKeyEvent(keyCode, event) + } + } + + private fun handleHomeKeyEvent(keyCode: Int, event: KeyEvent): Boolean { + val visibleApps = getVisibleHomeApps() + if (visibleApps.isEmpty()) return false + + val focusedIndex = visibleApps.indexOf(activity?.currentFocus) + + when (event.action) { + KeyEvent.ACTION_DOWN -> { + when (keyCode) { + KeyEvent.KEYCODE_DPAD_UP -> { + if (event.repeatCount > 0) return true + if (focusedIndex > 0) { + visibleApps[focusedIndex - 1].requestFocus() + } else { + swipeDownAction() + } + return true + } + KeyEvent.KEYCODE_DPAD_DOWN -> { + if (event.repeatCount > 0) return true + if (focusedIndex < visibleApps.size - 1) { + visibleApps[focusedIndex + 1].requestFocus() + } else if (focusedIndex == visibleApps.size - 1) { + showAppList(Constants.FLAG_LAUNCH_APP) + } + return true + } + KeyEvent.KEYCODE_DPAD_LEFT -> { + if (dpadLeftKeyDownTime == 0L) dpadLeftKeyDownTime = System.currentTimeMillis() + if (event.repeatCount > 0) { + val elapsed = System.currentTimeMillis() - dpadLeftKeyDownTime + if (elapsed >= Constants.LONG_PRESS_DELAY_MS) { + dpadLeftKeyDownTime = 0L + openSwipeLeftApp() + } + } + return true + } + KeyEvent.KEYCODE_DPAD_RIGHT -> { + if (dpadRightKeyDownTime == 0L) dpadRightKeyDownTime = System.currentTimeMillis() + if (event.repeatCount > 0) { + val elapsed = System.currentTimeMillis() - dpadRightKeyDownTime + if (elapsed >= Constants.LONG_PRESS_DELAY_MS) { + dpadRightKeyDownTime = 0L + openSwipeRightApp() + } + } + return true + } + KeyEvent.KEYCODE_DPAD_CENTER, + KeyEvent.KEYCODE_ENTER, + KeyEvent.KEYCODE_NUMPAD_ENTER -> return false + } + } + KeyEvent.ACTION_UP -> { + when (keyCode) { + KeyEvent.KEYCODE_DPAD_DOWN -> return true + KeyEvent.KEYCODE_DPAD_LEFT -> { + dpadLeftKeyDownTime = 0L + return true + } + KeyEvent.KEYCODE_DPAD_RIGHT -> { + dpadRightKeyDownTime = 0L + return true + } + KeyEvent.KEYCODE_DPAD_CENTER, + KeyEvent.KEYCODE_ENTER, + KeyEvent.KEYCODE_NUMPAD_ENTER -> return false + } + } + } + return false + } + + private fun requestInitialFocus() { + if (binding.mainLayout.isInTouchMode) return + getVisibleHomeApps().firstOrNull()?.requestFocus() + } + + private fun getVisibleHomeApps(): List<View> { + return listOf( + binding.homeApp1, + binding.homeApp2, + binding.homeApp3, + binding.homeApp4, + binding.homeApp5, + binding.homeApp6, + binding.homeApp7, + binding.homeApp8, + ).filter { it.visibility == View.VISIBLE } } private fun initSwipeTouchListener() { @@ -226,8 +323,6 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener private fun initClickListeners() { binding.lock.setOnClickListener(this) - // Home button for recents feature disabled - // binding.recents.setOnClickListener(this) binding.clock.setOnClickListener(this) binding.date.setOnClickListener(this) binding.clock.setOnLongClickListener(this) @@ -236,6 +331,55 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener binding.setDefaultLauncher.setOnLongClickListener(this) binding.tvScreenTime.setOnClickListener(this) binding.tvScreenTime.setOnLongClickListener(this) + + listOf( + binding.homeApp1, + binding.homeApp2, + binding.homeApp3, + binding.homeApp4, + binding.homeApp5, + binding.homeApp6, + binding.homeApp7, + binding.homeApp8, + ).forEach { homeApp -> + homeApp.setOnClickListener(this) + homeApp.setOnLongClickListener(this) + homeApp.setOnKeyListener { view, keyCode, event -> + when (keyCode) { + KeyEvent.KEYCODE_DPAD_DOWN -> { + if (event.action != KeyEvent.ACTION_DOWN) return@setOnKeyListener true + if (event.repeatCount > 0) return@setOnKeyListener true + val visibleApps = getVisibleHomeApps() + val focusedIndex = visibleApps.indexOf(view) + if (focusedIndex < 0) return@setOnKeyListener true + if (focusedIndex < visibleApps.size - 1) { + visibleApps[focusedIndex + 1].requestFocus() + } else { + showAppList(Constants.FLAG_LAUNCH_APP) + } + true + } + KeyEvent.KEYCODE_ENTER, + KeyEvent.KEYCODE_DPAD_CENTER, + KeyEvent.KEYCODE_NUMPAD_ENTER -> { + when (event.action) { + KeyEvent.ACTION_DOWN -> { + if (event.repeatCount > 0) { + view.performLongClick() + } + true + } + KeyEvent.ACTION_UP -> { + if (event.repeatCount == 0) view.performClick() + true + } + else -> false + } + } + else -> false + } + } + } } private fun setHomeAlignment(horizontalGravity: Int = prefs.homeAlignment) { @@ -257,7 +401,6 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener binding.clock.isVisible = Constants.DateTime.isTimeVisible(prefs.dateTimeVisibility) binding.date.isVisible = Constants.DateTime.isDateVisible(prefs.dateTimeVisibility) -// var dateText = SimpleDateFormat("EEE, d MMM", Locale.getDefault()).format(Date()) val dateFormat = SimpleDateFormat("EEE, d MMM", Locale.getDefault()) var dateText = dateFormat.format(Date()) @@ -299,6 +442,7 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener private fun populateHomeScreen(appCountUpdated: Boolean) { if (appCountUpdated) hideHomeApps() + restoreHomeAppFocusability() populateDateTime() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) @@ -371,14 +515,10 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener isShortcut: Boolean, shortcutId: String?, ): Boolean { - // Get user handle for the app/shortcut val userHandle = getUserHandleFromString(requireContext(), userString) - // If it's a shortcut, verify it still exists if (isShortcut) { val launcherApps = requireContext().getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps - - // Query for the specific shortcut val query = LauncherApps.ShortcutQuery().apply { setPackage(packageName) setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED) @@ -386,7 +526,6 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener try { val shortcuts = launcherApps.getShortcuts(query, userHandle) - // Check if our shortcut still exists if (shortcuts?.any { it.id == shortcutId } == true) { textView.text = appName return true @@ -400,7 +539,6 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener } } - // Regular app check if (isPackageInstalled(requireContext(), packageName, userString)) { textView.text = appName return true @@ -409,15 +547,33 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener return false } + private fun restoreHomeAppFocusability() { + listOf( + binding.homeApp1, + binding.homeApp2, + binding.homeApp3, + binding.homeApp4, + binding.homeApp5, + binding.homeApp6, + binding.homeApp7, + binding.homeApp8, + ).forEach { it.isFocusable = true } + } + private fun hideHomeApps() { - binding.homeApp1.visibility = View.GONE - binding.homeApp2.visibility = View.GONE - binding.homeApp3.visibility = View.GONE - binding.homeApp4.visibility = View.GONE - binding.homeApp5.visibility = View.GONE - binding.homeApp6.visibility = View.GONE - binding.homeApp7.visibility = View.GONE - binding.homeApp8.visibility = View.GONE + listOf( + binding.homeApp1, + binding.homeApp2, + binding.homeApp3, + binding.homeApp4, + binding.homeApp5, + binding.homeApp6, + binding.homeApp7, + binding.homeApp8, + ).forEach { + it.visibility = View.GONE + it.isFocusable = false + } } private fun launchAppOrShortcut( @@ -715,4 +871,4 @@ class HomeFragment : Fragment(), View.OnClickListener, View.OnLongClickListener super.onDestroyView() _binding = null } -}
\ No newline at end of file +} diff --git a/app/src/main/res/layout/adapter_app_drawer.xml b/app/src/main/res/layout/adapter_app_drawer.xml index 9168741..a68f88d 100644 --- a/app/src/main/res/layout/adapter_app_drawer.xml +++ b/app/src/main/res/layout/adapter_app_drawer.xml @@ -6,15 +6,26 @@ android:layout_height="wrap_content" android:animateLayoutChanges="true"> - <TextView - android:id="@+id/appTitle" - style="@style/TextLarge" + <LinearLayout + android:id="@+id/appRow" android:layout_width="match_parent" android:layout_height="wrap_content" - android:maxLines="1" + android:focusable="true" + android:focusableInTouchMode="false" + android:gravity="center_vertical" + android:orientation="horizontal" android:paddingHorizontal="24dp" - android:paddingVertical="@dimen/app_padding_vertical" - android:text="@string/app" /> + android:paddingVertical="@dimen/app_padding_vertical"> + + <TextView + android:id="@+id/appTitle" + style="@style/TextLarge" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:maxLines="1" + android:text="@string/app" /> + </LinearLayout> <ImageView android:id="@+id/otherProfileIndicator" diff --git a/app/src/main/res/layout/fragment_app_drawer.xml b/app/src/main/res/layout/fragment_app_drawer.xml index 7935654..665a01a 100644 --- a/app/src/main/res/layout/fragment_app_drawer.xml +++ b/app/src/main/res/layout/fragment_app_drawer.xml @@ -64,7 +64,9 @@ android:layout_marginBottom="24dp" android:clipChildren="false" android:clipToPadding="false" + android:descendantFocusability="afterDescendants" android:fadingEdgeLength="24dp" + android:focusable="true" android:requiresFadingEdge="vertical" /> </LinearLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 385532e..7de8a4a 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -88,6 +88,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_1" @@ -99,6 +101,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_2" @@ -110,6 +114,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_3" @@ -121,6 +127,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_4" @@ -132,6 +140,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_5" @@ -143,6 +153,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_6" @@ -154,6 +166,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_7" @@ -165,6 +179,8 @@ style="@style/TextLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="false" android:hint="@string/app" android:paddingVertical="@dimen/home_app_padding_vertical" android:tag="@string/tag_8" |
