mirror of
https://github.com/He4eT/yamf_launcher.git
synced 2026-05-04 17:37:25 +00:00
Added Accessibility Actions for the context menu actions of each app and entering the preferences activity from home screen
This commit is contained in:
parent
5038074341
commit
a088a1edeb
3 changed files with 148 additions and 109 deletions
|
|
@ -16,136 +16,67 @@ import android.widget.EditText
|
|||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.widget.AppCompatButton
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import eu.ottop.yamlauncher.databinding.ActivityMainBinding
|
||||
import eu.ottop.yamlauncher.settings.SharedPreferenceManager
|
||||
import eu.ottop.yamlauncher.utils.Animations
|
||||
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(
|
||||
activity: MainActivity,
|
||||
binding: ActivityMainBinding,
|
||||
textView: TextView,
|
||||
editLayout: LinearLayout,
|
||||
actionMenu: View,
|
||||
searchView: EditText,
|
||||
appInfo: ApplicationInfo,
|
||||
userHandle: UserHandle,
|
||||
workProfile: Int,
|
||||
launcherApps: LauncherApps,
|
||||
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 {
|
||||
|
||||
// Launch app info in phone settings
|
||||
if (appActivity != null) {
|
||||
launcherApps.startAppDetailsActivity(
|
||||
appActivity.componentName,
|
||||
userHandle,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
val intent = Intent(Intent.ACTION_DELETE)
|
||||
intent.data = Uri.parse("package:${appInfo.packageName}")
|
||||
intent.putExtra(Intent.EXTRA_USER, userHandle)
|
||||
activity.startActivity(intent)
|
||||
|
||||
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 {
|
||||
textView.visibility = View.INVISIBLE
|
||||
animations.fadeViewIn(editLayout)
|
||||
animations.fadeViewOut(actionMenu)
|
||||
val editText = editLayout.findViewById<EditText>(R.id.appNameEdit)
|
||||
val resetButton = editLayout.findViewById<AppCompatButton>(R.id.reset)
|
||||
renameApp(textView, editLayout, actionMenu, appActivity, appInfo, userHandle, workProfile)
|
||||
}
|
||||
|
||||
val app = Triple(appActivity!!, userHandle, workProfile)
|
||||
|
||||
searchView.visibility = View.INVISIBLE
|
||||
editText.requestFocus()
|
||||
|
||||
// Open keyboard
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
handler.postDelayed({
|
||||
val imm =
|
||||
activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
|
||||
}, 100)
|
||||
|
||||
binding.root.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom ->
|
||||
|
||||
// If the keyboard is closed, exit editing mode
|
||||
if (bottom - top > oldBottom - oldTop) {
|
||||
editLayout.clearFocus()
|
||||
|
||||
animations.fadeViewOut(editLayout)
|
||||
textView.visibility = View.VISIBLE
|
||||
searchView.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
editText.setOnEditorActionListener { _, actionId, _ ->
|
||||
|
||||
// Once the new name is confirmed, close the keyboard, save the new app name and update the apps on screen
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
val imm =
|
||||
activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(editText.windowToken, 0)
|
||||
sharedPreferenceManager.setAppName(
|
||||
appInfo.packageName,
|
||||
workProfile,
|
||||
editText.text.toString()
|
||||
)
|
||||
activity.lifecycleScope.launch {
|
||||
activity.applySearch()
|
||||
}
|
||||
|
||||
|
||||
return@setOnEditorActionListener true
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
resetButton.setOnClickListener {
|
||||
|
||||
// If reset is pressed, close keyboard, remove saved edited name and update the apps on screen
|
||||
val imm =
|
||||
activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(editLayout.windowToken, 0)
|
||||
sharedPreferenceManager.resetAppName(
|
||||
app.first.applicationInfo.packageName,
|
||||
app.third
|
||||
)
|
||||
|
||||
activity.lifecycleScope.launch {
|
||||
activity.applySearch()
|
||||
}
|
||||
}
|
||||
ViewCompat.addAccessibilityAction(textView, "Hide app") { _, _ ->
|
||||
hideApp(editLayout, textView, actionMenu, appInfo, workProfile)
|
||||
true
|
||||
}
|
||||
|
||||
actionMenu.findViewById<TextView>(R.id.hide).setOnClickListener {
|
||||
editLayout.visibility = View.GONE
|
||||
textView.visibility = View.GONE
|
||||
actionMenu.visibility = View.GONE
|
||||
activity.lifecycleScope.launch {
|
||||
sharedPreferenceManager.setAppHidden(appInfo.packageName, workProfile, true)
|
||||
activity.refreshAppMenu()
|
||||
}
|
||||
hideApp(editLayout, textView, actionMenu, appInfo, workProfile)
|
||||
}
|
||||
|
||||
actionMenu.findViewById<TextView>(R.id.close).setOnClickListener {
|
||||
|
|
@ -153,4 +84,107 @@ class AppActionMenu {
|
|||
textView.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
private fun appInfo(
|
||||
appActivity: LauncherActivityInfo?,
|
||||
userHandle: UserHandle
|
||||
) {
|
||||
// Launch app info in phone settings
|
||||
if (appActivity != null) {
|
||||
launcherApps.startAppDetailsActivity(
|
||||
appActivity.componentName,
|
||||
userHandle,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun uninstallApp(appInfo: ApplicationInfo, userHandle: UserHandle) {
|
||||
val intent = Intent(Intent.ACTION_DELETE)
|
||||
intent.data = Uri.parse("package:${appInfo.packageName}")
|
||||
intent.putExtra(Intent.EXTRA_USER, userHandle)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
|
||||
private fun renameApp(textView: TextView, editLayout: LinearLayout, actionMenu: View, appActivity: LauncherActivityInfo?, appInfo: ApplicationInfo, userHandle: UserHandle, workProfile: Int) {
|
||||
textView.visibility = View.INVISIBLE
|
||||
animations.fadeViewIn(editLayout)
|
||||
animations.fadeViewOut(actionMenu)
|
||||
val editText = editLayout.findViewById<EditText>(R.id.appNameEdit)
|
||||
val resetButton = editLayout.findViewById<AppCompatButton>(R.id.reset)
|
||||
|
||||
val app = Triple(appActivity!!, userHandle, workProfile)
|
||||
|
||||
searchView.visibility = View.INVISIBLE
|
||||
editText.requestFocus()
|
||||
|
||||
// Open keyboard
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
handler.postDelayed({
|
||||
val imm =
|
||||
activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
|
||||
}, 100)
|
||||
|
||||
binding.root.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom ->
|
||||
|
||||
// If the keyboard is closed, exit editing mode
|
||||
if (bottom - top > oldBottom - oldTop) {
|
||||
editLayout.clearFocus()
|
||||
|
||||
animations.fadeViewOut(editLayout)
|
||||
textView.visibility = View.VISIBLE
|
||||
searchView.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
editText.setOnEditorActionListener { _, actionId, _ ->
|
||||
|
||||
// Once the new name is confirmed, close the keyboard, save the new app name and update the apps on screen
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
val imm =
|
||||
activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(editText.windowToken, 0)
|
||||
sharedPreferenceManager.setAppName(
|
||||
appInfo.packageName,
|
||||
workProfile,
|
||||
editText.text.toString()
|
||||
)
|
||||
activity.lifecycleScope.launch {
|
||||
activity.applySearch()
|
||||
}
|
||||
|
||||
|
||||
return@setOnEditorActionListener true
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
resetButton.setOnClickListener {
|
||||
|
||||
// If reset is pressed, close keyboard, remove saved edited name and update the apps on screen
|
||||
val imm =
|
||||
activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.hideSoftInputFromWindow(editLayout.windowToken, 0)
|
||||
sharedPreferenceManager.resetAppName(
|
||||
app.first.applicationInfo.packageName,
|
||||
app.third
|
||||
)
|
||||
|
||||
activity.lifecycleScope.launch {
|
||||
activity.applySearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideApp(editLayout: LinearLayout, textView: TextView, actionMenu: View, appInfo: ApplicationInfo, workProfile: Int) {
|
||||
editLayout.visibility = View.GONE
|
||||
textView.visibility = View.GONE
|
||||
actionMenu.visibility = View.GONE
|
||||
activity.lifecycleScope.launch {
|
||||
sharedPreferenceManager.setAppHidden(appInfo.packageName, workProfile, true)
|
||||
activity.refreshAppMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package eu.ottop.yamlauncher
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.content.pm.LauncherApps
|
||||
|
|
@ -17,28 +16,30 @@ import android.widget.TextView
|
|||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.textfield.TextInputEditText
|
||||
import eu.ottop.yamlauncher.databinding.ActivityMainBinding
|
||||
import eu.ottop.yamlauncher.settings.SharedPreferenceManager
|
||||
import eu.ottop.yamlauncher.utils.AppUtils
|
||||
import eu.ottop.yamlauncher.utils.UIUtils
|
||||
|
||||
|
||||
class AppMenuAdapter(
|
||||
|
||||
private val context: Context,
|
||||
private val activity: MainActivity,
|
||||
binding: ActivityMainBinding,
|
||||
private var apps: MutableList<Triple<LauncherActivityInfo, UserHandle, Int>>,
|
||||
private val itemClickListener: OnItemClickListener,
|
||||
private val shortcutListener: OnShortcutListener,
|
||||
private val itemLongClickListener: OnItemLongClickListener,
|
||||
launcherApps: LauncherApps
|
||||
private val launcherApps: LauncherApps
|
||||
) :
|
||||
RecyclerView.Adapter<AppMenuAdapter.AppViewHolder>() {
|
||||
|
||||
// If the menu is opened to select shortcuts, the below variable is set
|
||||
var shortcutTextView: TextView? = null
|
||||
|
||||
private val sharedPreferenceManager = SharedPreferenceManager(context)
|
||||
private val uiUtils = UIUtils(context)
|
||||
private val appUtils = AppUtils(context, launcherApps)
|
||||
private val sharedPreferenceManager = SharedPreferenceManager(activity)
|
||||
private val uiUtils = UIUtils(activity)
|
||||
private val appUtils = AppUtils(activity, launcherApps)
|
||||
private var appActionMenu = AppActionMenu(activity, binding, launcherApps, activity.findViewById(R.id.searchView))
|
||||
|
||||
interface OnItemClickListener {
|
||||
fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle)
|
||||
|
|
@ -64,7 +65,7 @@ class AppMenuAdapter(
|
|||
private val listItem: FrameLayout = itemView.findViewById(R.id.listItem)
|
||||
val textView: TextView = listItem.findViewById(R.id.appName)
|
||||
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)
|
||||
|
||||
init {
|
||||
|
|
@ -121,12 +122,12 @@ class AppMenuAdapter(
|
|||
|
||||
// Set initial drawables
|
||||
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 =
|
||||
BlendModeColorFilter(sharedPreferenceManager.getTextColor(), BlendMode.SRC_ATOP)
|
||||
}
|
||||
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)
|
||||
|
|
@ -142,7 +143,7 @@ class AppMenuAdapter(
|
|||
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.
|
||||
val appLabel: CharSequence = appInfo?.let { context.packageManager.getApplicationLabel(it) } ?: "Removing..."
|
||||
val appLabel: CharSequence = appInfo?.let { activity.packageManager.getApplicationLabel(it) } ?: "Removing..."
|
||||
|
||||
if (appInfo != null) {
|
||||
holder.textView.text = sharedPreferenceManager.getAppName(
|
||||
|
|
@ -165,6 +166,21 @@ class AppMenuAdapter(
|
|||
else {holder.textView.text = appLabel}
|
||||
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import androidx.activity.OnBackPressedCallback
|
|||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.marginLeft
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
|
@ -64,7 +65,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
private lateinit var uiUtils: UIUtils
|
||||
private lateinit var gestureUtils: GestureUtils
|
||||
|
||||
private var appActionMenu = AppActionMenu()
|
||||
private val appMenuLinearLayoutManager = AppMenuLinearLayoutManager(this@MainActivity)
|
||||
private val appMenuEdgeFactory = AppMenuEdgeFactory(this@MainActivity)
|
||||
|
||||
|
|
@ -317,6 +317,11 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
true
|
||||
}
|
||||
|
||||
ViewCompat.addAccessibilityAction(binding.homeView, "Preferences") { _, _ ->
|
||||
startActivity(Intent(this@MainActivity, SettingsActivity::class.java))
|
||||
true
|
||||
}
|
||||
|
||||
// Return to home on back
|
||||
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
|
|
@ -526,7 +531,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
}
|
||||
|
||||
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
|
||||
recyclerView = findViewById(R.id.recyclerView)
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
@ -696,22 +701,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
) {
|
||||
textView.visibility = View.INVISIBLE
|
||||
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() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue