Added Accessibility Actions for the context menu actions of each app and entering the preferences activity from home screen

This commit is contained in:
ottoptj 2024-08-30 12:35:16 +03:00
commit a088a1edeb
3 changed files with 148 additions and 109 deletions

View file

@ -16,32 +16,79 @@ import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.AppCompatButton import androidx.appcompat.widget.AppCompatButton
import androidx.core.view.ViewCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import eu.ottop.yamlauncher.databinding.ActivityMainBinding import eu.ottop.yamlauncher.databinding.ActivityMainBinding
import eu.ottop.yamlauncher.settings.SharedPreferenceManager import eu.ottop.yamlauncher.settings.SharedPreferenceManager
import eu.ottop.yamlauncher.utils.Animations import eu.ottop.yamlauncher.utils.Animations
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class AppActionMenu { class AppActionMenu(private val activity: MainActivity, private val binding: ActivityMainBinding, private val launcherApps: LauncherApps, private val searchView: EditText) {
private val animations = Animations(activity)
private val sharedPreferenceManager = SharedPreferenceManager(activity)
fun setActionListeners( fun setActionListeners(
activity: MainActivity,
binding: ActivityMainBinding,
textView: TextView, textView: TextView,
editLayout: LinearLayout, editLayout: LinearLayout,
actionMenu: View, actionMenu: View,
searchView: EditText,
appInfo: ApplicationInfo, appInfo: ApplicationInfo,
userHandle: UserHandle, userHandle: UserHandle,
workProfile: Int, workProfile: Int,
launcherApps: LauncherApps,
appActivity: LauncherActivityInfo? appActivity: LauncherActivityInfo?
){ ){
val animations = Animations(activity)
val sharedPreferenceManager = SharedPreferenceManager(activity)
ViewCompat.addAccessibilityAction(textView, "App info") { _, _ ->
appInfo(appActivity, userHandle)
true
}
actionMenu.findViewById<TextView>(R.id.info).setOnClickListener { actionMenu.findViewById<TextView>(R.id.info).setOnClickListener {
appInfo(appActivity, userHandle)
animations.fadeViewOut(actionMenu)
textView.visibility = View.VISIBLE
}
ViewCompat.addAccessibilityAction(textView, "Uninstall app") { _, _ ->
uninstallApp(appInfo, userHandle)
true
}
actionMenu.findViewById<TextView>(R.id.uninstall).setOnClickListener {
uninstallApp(appInfo, userHandle)
animations.fadeViewOut(actionMenu)
textView.visibility = View.VISIBLE
}
ViewCompat.addAccessibilityAction(textView, "Rename app") { _, _ ->
renameApp(textView, editLayout, actionMenu, appActivity, appInfo, userHandle, workProfile)
true
}
actionMenu.findViewById<TextView>(R.id.rename).setOnClickListener {
renameApp(textView, editLayout, actionMenu, appActivity, appInfo, userHandle, workProfile)
}
ViewCompat.addAccessibilityAction(textView, "Hide app") { _, _ ->
hideApp(editLayout, textView, actionMenu, appInfo, workProfile)
true
}
actionMenu.findViewById<TextView>(R.id.hide).setOnClickListener {
hideApp(editLayout, textView, actionMenu, appInfo, workProfile)
}
actionMenu.findViewById<TextView>(R.id.close).setOnClickListener {
animations.fadeViewOut(actionMenu)
textView.visibility = View.VISIBLE
}
}
private fun appInfo(
appActivity: LauncherActivityInfo?,
userHandle: UserHandle
) {
// Launch app info in phone settings // Launch app info in phone settings
if (appActivity != null) { if (appActivity != null) {
launcherApps.startAppDetailsActivity( launcherApps.startAppDetailsActivity(
@ -51,23 +98,16 @@ class AppActionMenu {
null null
) )
} }
animations.fadeViewOut(actionMenu)
textView.visibility = View.VISIBLE
} }
actionMenu.findViewById<TextView>(R.id.uninstall).setOnClickListener { private fun uninstallApp(appInfo: ApplicationInfo, userHandle: UserHandle) {
val intent = Intent(Intent.ACTION_DELETE) val intent = Intent(Intent.ACTION_DELETE)
intent.data = Uri.parse("package:${appInfo.packageName}") intent.data = Uri.parse("package:${appInfo.packageName}")
intent.putExtra(Intent.EXTRA_USER, userHandle) intent.putExtra(Intent.EXTRA_USER, userHandle)
activity.startActivity(intent) activity.startActivity(intent)
animations.fadeViewOut(actionMenu)
textView.visibility = View.VISIBLE
} }
actionMenu.findViewById<TextView>(R.id.rename).setOnClickListener { private fun renameApp(textView: TextView, editLayout: LinearLayout, actionMenu: View, appActivity: LauncherActivityInfo?, appInfo: ApplicationInfo, userHandle: UserHandle, workProfile: Int) {
textView.visibility = View.INVISIBLE textView.visibility = View.INVISIBLE
animations.fadeViewIn(editLayout) animations.fadeViewIn(editLayout)
animations.fadeViewOut(actionMenu) animations.fadeViewOut(actionMenu)
@ -138,7 +178,7 @@ class AppActionMenu {
} }
} }
actionMenu.findViewById<TextView>(R.id.hide).setOnClickListener { private fun hideApp(editLayout: LinearLayout, textView: TextView, actionMenu: View, appInfo: ApplicationInfo, workProfile: Int) {
editLayout.visibility = View.GONE editLayout.visibility = View.GONE
textView.visibility = View.GONE textView.visibility = View.GONE
actionMenu.visibility = View.GONE actionMenu.visibility = View.GONE
@ -147,10 +187,4 @@ class AppActionMenu {
activity.refreshAppMenu() activity.refreshAppMenu()
} }
} }
actionMenu.findViewById<TextView>(R.id.close).setOnClickListener {
animations.fadeViewOut(actionMenu)
textView.visibility = View.VISIBLE
}
}
} }

View file

@ -1,7 +1,6 @@
package eu.ottop.yamlauncher package eu.ottop.yamlauncher
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
@ -17,28 +16,30 @@ import android.widget.TextView
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import eu.ottop.yamlauncher.databinding.ActivityMainBinding
import eu.ottop.yamlauncher.settings.SharedPreferenceManager import eu.ottop.yamlauncher.settings.SharedPreferenceManager
import eu.ottop.yamlauncher.utils.AppUtils import eu.ottop.yamlauncher.utils.AppUtils
import eu.ottop.yamlauncher.utils.UIUtils import eu.ottop.yamlauncher.utils.UIUtils
class AppMenuAdapter( class AppMenuAdapter(
private val activity: MainActivity,
private val context: Context, binding: ActivityMainBinding,
private var apps: MutableList<Triple<LauncherActivityInfo, UserHandle, Int>>, private var apps: MutableList<Triple<LauncherActivityInfo, UserHandle, Int>>,
private val itemClickListener: OnItemClickListener, private val itemClickListener: OnItemClickListener,
private val shortcutListener: OnShortcutListener, private val shortcutListener: OnShortcutListener,
private val itemLongClickListener: OnItemLongClickListener, private val itemLongClickListener: OnItemLongClickListener,
launcherApps: LauncherApps private val launcherApps: LauncherApps
) : ) :
RecyclerView.Adapter<AppMenuAdapter.AppViewHolder>() { RecyclerView.Adapter<AppMenuAdapter.AppViewHolder>() {
// If the menu is opened to select shortcuts, the below variable is set // If the menu is opened to select shortcuts, the below variable is set
var shortcutTextView: TextView? = null var shortcutTextView: TextView? = null
private val sharedPreferenceManager = SharedPreferenceManager(context) private val sharedPreferenceManager = SharedPreferenceManager(activity)
private val uiUtils = UIUtils(context) private val uiUtils = UIUtils(activity)
private val appUtils = AppUtils(context, launcherApps) private val appUtils = AppUtils(activity, launcherApps)
private var appActionMenu = AppActionMenu(activity, binding, launcherApps, activity.findViewById(R.id.searchView))
interface OnItemClickListener { interface OnItemClickListener {
fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle)
@ -64,7 +65,7 @@ class AppMenuAdapter(
private val listItem: FrameLayout = itemView.findViewById(R.id.listItem) private val listItem: FrameLayout = itemView.findViewById(R.id.listItem)
val textView: TextView = listItem.findViewById(R.id.appName) val textView: TextView = listItem.findViewById(R.id.appName)
val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.actionMenu) val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.actionMenu)
private val editView: LinearLayout = listItem.findViewById(R.id.renameView) val editView: LinearLayout = listItem.findViewById(R.id.renameView)
val editText: TextInputEditText = editView.findViewById(R.id.appNameEdit) val editText: TextInputEditText = editView.findViewById(R.id.appNameEdit)
init { init {
@ -121,12 +122,12 @@ class AppMenuAdapter(
// Set initial drawables // Set initial drawables
if (app.third != 0) { if (app.third != 0) {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_work_app, null),null, ResourcesCompat.getDrawable(context.resources, R.drawable.ic_empty, null),null) holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_work_app, null),null, ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null)
holder.textView.compoundDrawables[0].colorFilter = holder.textView.compoundDrawables[0].colorFilter =
BlendModeColorFilter(sharedPreferenceManager.getTextColor(), BlendMode.SRC_ATOP) BlendModeColorFilter(sharedPreferenceManager.getTextColor(), BlendMode.SRC_ATOP)
} }
else { else {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_empty, null),null,ResourcesCompat.getDrawable(context.resources, R.drawable.ic_empty, null),null) holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null,ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null)
} }
uiUtils.setAppAlignment(holder.textView, holder.editText) uiUtils.setAppAlignment(holder.textView, holder.editText)
@ -142,7 +143,7 @@ class AppMenuAdapter(
holder.textView.setTextColor(sharedPreferenceManager.getTextColor()) holder.textView.setTextColor(sharedPreferenceManager.getTextColor())
// Set app name on the menu. If the app has been uninstalled, replace it with "Removing" until the app menu updates. // Set app name on the menu. If the app has been uninstalled, replace it with "Removing" until the app menu updates.
val appLabel: CharSequence = appInfo?.let { context.packageManager.getApplicationLabel(it) } ?: "Removing..." val appLabel: CharSequence = appInfo?.let { activity.packageManager.getApplicationLabel(it) } ?: "Removing..."
if (appInfo != null) { if (appInfo != null) {
holder.textView.text = sharedPreferenceManager.getAppName( holder.textView.text = sharedPreferenceManager.getAppName(
@ -165,6 +166,21 @@ class AppMenuAdapter(
else {holder.textView.text = appLabel} else {holder.textView.text = appLabel}
holder.textView.visibility = View.VISIBLE holder.textView.visibility = View.VISIBLE
if (appInfo != null) {
val appActivity = launcherApps.getActivityList(appInfo.packageName, app.second).firstOrNull()
appActionMenu.setActionListeners(
holder.textView,
holder.editView,
holder.actionMenuLayout,
appInfo,
app.second,
app.third,
appActivity
)
}
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {

View file

@ -28,6 +28,7 @@ import androidx.activity.OnBackPressedCallback
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.view.ViewCompat
import androidx.core.view.marginLeft import androidx.core.view.marginLeft
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -64,7 +65,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
private lateinit var uiUtils: UIUtils private lateinit var uiUtils: UIUtils
private lateinit var gestureUtils: GestureUtils private lateinit var gestureUtils: GestureUtils
private var appActionMenu = AppActionMenu()
private val appMenuLinearLayoutManager = AppMenuLinearLayoutManager(this@MainActivity) private val appMenuLinearLayoutManager = AppMenuLinearLayoutManager(this@MainActivity)
private val appMenuEdgeFactory = AppMenuEdgeFactory(this@MainActivity) private val appMenuEdgeFactory = AppMenuEdgeFactory(this@MainActivity)
@ -317,6 +317,11 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
true true
} }
ViewCompat.addAccessibilityAction(binding.homeView, "Preferences") { _, _ ->
startActivity(Intent(this@MainActivity, SettingsActivity::class.java))
true
}
// Return to home on back // Return to home on back
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
@ -526,7 +531,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
} }
private suspend fun setupRecyclerView(newApps: MutableList<Triple<LauncherActivityInfo, UserHandle, Int>>) { private suspend fun setupRecyclerView(newApps: MutableList<Triple<LauncherActivityInfo, UserHandle, Int>>) {
adapter = AppMenuAdapter(this@MainActivity, newApps, this@MainActivity, this@MainActivity, this@MainActivity, launcherApps) adapter = AppMenuAdapter(this@MainActivity, binding, newApps, this@MainActivity, this@MainActivity, this@MainActivity, launcherApps)
appMenuLinearLayoutManager.stackFromEnd = true appMenuLinearLayoutManager.stackFromEnd = true
recyclerView = findViewById(R.id.recyclerView) recyclerView = findViewById(R.id.recyclerView)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
@ -696,22 +701,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
) { ) {
textView.visibility = View.INVISIBLE textView.visibility = View.INVISIBLE
animations.fadeViewIn(actionMenuLayout) animations.fadeViewIn(actionMenuLayout)
val appActivity =
launcherApps.getActivityList(appInfo.applicationInfo.packageName, userHandle)
.firstOrNull()
appActionMenu.setActionListeners(
this@MainActivity,
binding,
textView,
editView,
actionMenuLayout,
searchView,
appInfo.applicationInfo,
userHandle,
userProfile,
launcherApps,
appActivity
)
} }
open inner class GestureListener : GestureDetector.SimpleOnGestureListener() { open inner class GestureListener : GestureDetector.SimpleOnGestureListener() {