Unhiding apps works now

This commit is contained in:
ottoptj 2024-08-01 00:15:13 +03:00
commit e2cf32eec6
4 changed files with 276 additions and 80 deletions

View file

@ -24,7 +24,7 @@ import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
class AppMenuAdapter(
private val activity: MainActivity,
private val activity: Context,
var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
private val itemClickListener: OnItemClickListener,
private val shortcutListener: OnShortcutListener,

View file

@ -14,43 +14,22 @@ import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
import kotlin.time.Duration.Companion.seconds
class HiddenAppsAdapter(
private val activity: Context,
var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
private val itemClickListener: OnItemClickListener,
private val shortcutListener: OnShortcutListener,
private val itemLongClickListener: OnItemLongClickListener
private val itemClickListener: OnItemClickListener
) :
RecyclerView.Adapter<HiddenAppsAdapter.AppViewHolder>() {
var menuMode: String = "app"
var shortcutTextView: TextView? = null
private val sharedPreferenceManager = SharedPreferenceManager()
private var preferences = PreferenceManager.getDefaultSharedPreferences(activity)
interface OnItemClickListener {
fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle)
}
interface OnShortcutListener {
fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int, shortcutView: TextView)
}
interface OnItemLongClickListener {
fun onItemLongClick(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
userProfile: Int,
textView: TextView,
actionMenuLayout: LinearLayout,
editView: LinearLayout,
position: Int
)
fun onItemClick(appInfo: LauncherActivityInfo, profile: Int)
}
inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@ -65,33 +44,9 @@ class HiddenAppsAdapter(
editView.visibility = View.INVISIBLE
textView.setOnClickListener {
val position = bindingAdapterPosition
val app = apps[position].first
if (menuMode == "shortcut") {
shortcutListener.onShortcut(app, apps[position].second.first, textView, apps[position].second.second, shortcutTextView!!)
}
else if (menuMode == "app") {
itemClickListener.onItemClick(app, apps[position].second.first)
}
}
if (menuMode == "app") {
textView.setOnLongClickListener {
val position = bindingAdapterPosition
val app = apps[position].first
itemLongClickListener.onItemLongClick(
app,
apps[position].second.first,
apps[position].second.second,
textView,
actionMenuLayout,
editView,
position
)
return@setOnLongClickListener true
}
val position = bindingAdapterPosition
val app = apps[position].first
itemClickListener.onItemClick(app, apps[position].second.second)
}
}

View file

@ -1,18 +1,18 @@
package eu.ottop.yamlauncher
import android.app.Activity
import android.app.AlertDialog
import android.content.pm.LauncherActivityInfo
import android.os.Bundle
import android.os.UserHandle
import android.text.Editable
import android.text.TextWatcher
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.EditText
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
@ -24,11 +24,13 @@ private const val ARG_PARAM2 = "param2"
* Use the [HiddenAppsFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, HiddenAppsAdapter.OnShortcutListener, HiddenAppsAdapter.OnItemLongClickListener {
class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private val appUtils = AppUtils()
private val sharedPreferenceManager = SharedPreferenceManager()
private var adapter: HiddenAppsAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -50,13 +52,100 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, Hi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val adapter = HiddenAppsAdapter(requireContext(), appUtils.getHiddenApps(activity as Activity).toMutableList(), this, this, this)
adapter = HiddenAppsAdapter(requireContext(), appUtils.getHiddenApps(activity as Activity).toMutableList(), this)
val recyclerView = view.findViewById<RecyclerView>(R.id.hidden_app_recycler)
val appMenuEdgeFactory = AppMenuEdgeFactory(requireActivity())
recyclerView.edgeEffectFactory = appMenuEdgeFactory
recyclerView.adapter = adapter
recyclerView.scrollToPosition(0)
val searchView = view.findViewById<EditText>(R.id.hiddenAppSearch)
recyclerView.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom ->
if (bottom - top > oldBottom - oldTop) {
searchView.clearFocus()
}
}
searchView.addTextChangedListener(object :
TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
filterItems(searchView.text.toString())
}
})
}
private fun filterItems(query: String?) {
val cleanQuery = query?.clean()
val newFilteredApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
val updatedApps = appUtils.getHiddenApps(requireActivity())
getFilteredApps(cleanQuery, newFilteredApps, updatedApps)
applySearch(newFilteredApps)
}
private fun getFilteredApps(cleanQuery: String?, newFilteredApps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>, updatedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
if (cleanQuery.isNullOrEmpty()) {
newFilteredApps.addAll(updatedApps)
} else {
updatedApps.forEach {
val cleanItemText = sharedPreferenceManager.getAppName(requireActivity(), it.first.applicationInfo.packageName, it.second.second, requireActivity().packageManager.getApplicationLabel(it.first.applicationInfo)).toString().clean()
if (cleanItemText.contains(cleanQuery, ignoreCase = true)) {
newFilteredApps.add(it)
}
}
}
}
private fun applySearch(newFilteredApps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
adapter?.updateApps(newFilteredApps)
}
private fun String.clean(): String {
return this.replace("[^a-zA-Z0-9]".toRegex(), "")
}
private fun showConfirmationDialog(appInfo: LauncherActivityInfo, appName: String, profile: Int) {
AlertDialog.Builder(requireContext()).apply {
setTitle("Confirmation")
setMessage("Are you sure you want to unhide $appName?")
setPositiveButton("Yes") { _, _ ->
// Perform action on confirmation
performConfirmedAction(appInfo, appName, profile)
}
setNegativeButton("Cancel") { _, _ ->
// Handle cancellation
handleCancellation()
}
setOnCancelListener {
// Handle dialog cancel
handleCancellation()
}
}.create().show()
}
private fun performConfirmedAction(appInfo: LauncherActivityInfo, appName: String, profile: Int) {
sharedPreferenceManager.setAppVisible(requireContext(), appInfo.applicationInfo.packageName, profile)
adapter?.updateApps(appUtils.getHiddenApps(requireActivity()))
}
private fun handleCancellation() {
// Handle the cancellation of the dialog
}
companion object {
@ -79,29 +168,10 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, Hi
}
}
override fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) {
TODO("Not yet implemented")
override fun onItemClick(appInfo: LauncherActivityInfo, profile: Int) {
showConfirmationDialog(appInfo, sharedPreferenceManager.getAppName(requireContext(), appInfo.applicationInfo.packageName,profile, requireContext().packageManager.getApplicationLabel(appInfo.applicationInfo)).toString(), profile)
}
override fun onShortcut(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
textView: TextView,
userProfile: Int,
shortcutView: TextView
) {
TODO("Not yet implemented")
}
override fun onItemLongClick(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
userProfile: Int,
textView: TextView,
actionMenuLayout: LinearLayout,
editView: LinearLayout,
position: Int
) {
TODO("Not yet implemented")
}
}

View file

@ -0,0 +1,171 @@
package eu.ottop.yamlauncher
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.LauncherActivityInfo
import android.os.UserHandle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
class LocationListAdapter(
private val activity: Context,
var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
private val itemClickListener: OnItemClickListener,
private val shortcutListener: OnShortcutListener,
private val itemLongClickListener: OnItemLongClickListener
) :
RecyclerView.Adapter<LocationListAdapter.AppViewHolder>() {
var menuMode: String = "app"
var shortcutTextView: TextView? = null
private val sharedPreferenceManager = SharedPreferenceManager()
private var preferences = PreferenceManager.getDefaultSharedPreferences(activity)
interface OnItemClickListener {
fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle)
}
interface OnShortcutListener {
fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int, shortcutView: TextView)
}
interface OnItemLongClickListener {
fun onItemLongClick(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
userProfile: Int,
textView: TextView,
actionMenuLayout: LinearLayout,
editView: LinearLayout,
position: Int
)
}
inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val listItem: FrameLayout = itemView.findViewById(R.id.list_item)
val textView: TextView = listItem.findViewById(R.id.app_name)
val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.action_menu)
private val editView: LinearLayout = listItem.findViewById(R.id.rename_view)
val editText: EditText = editView.findViewById(R.id.app_name_edit)
init {
actionMenuLayout.visibility = View.INVISIBLE
editView.visibility = View.INVISIBLE
textView.setOnClickListener {
val position = bindingAdapterPosition
val app = apps[position].first
if (menuMode == "shortcut") {
shortcutListener.onShortcut(app, apps[position].second.first, textView, apps[position].second.second, shortcutTextView!!)
}
else if (menuMode == "app") {
itemClickListener.onItemClick(app, apps[position].second.first)
}
}
if (menuMode == "app") {
textView.setOnLongClickListener {
val position = bindingAdapterPosition
val app = apps[position].first
itemLongClickListener.onItemLongClick(
app,
apps[position].second.first,
apps[position].second.second,
textView,
actionMenuLayout,
editView,
position
)
return@setOnLongClickListener true
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.app_item_layout, parent, false)
return AppViewHolder(view)
}
override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
val app = apps[position]
if (app.second.second != 0) {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_work_app, null),null,null,null)
}
else {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null,null,null)
}
when (preferences.getString("appMenuAlignment", "left")) {
"left" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null, null, null)
holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.START
}
"center" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null,holder.textView.compoundDrawables.filterNotNull().first(), null)
holder.textView.gravity = Gravity.CENTER
}
"right" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(null,null, holder.textView.compoundDrawables.filterNotNull().first(), null)
holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.END
}
}
when (preferences.getString("appMenuSize", "medium")) {
"small" -> {
holder.textView.textSize = 24F
holder.editText.textSize = 24F
}
"medium" -> {
holder.textView.textSize = 26F
holder.editText.textSize = 26F
}
"large" -> {
holder.textView.textSize = 28F
holder.editText.textSize = 28F
}
}
val appInfo = app.first.activityInfo.applicationInfo
holder.textView.text = sharedPreferenceManager.getAppName(activity, app.first.applicationInfo.packageName,app.second.second, holder.itemView.context.packageManager.getApplicationLabel(appInfo))
holder.editText.setText(holder.textView.text)
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
holder.actionMenuLayout.findViewById<TextView>(R.id.uninstall).visibility = View.GONE
}
else {
holder.actionMenuLayout.findViewById<TextView>(R.id.uninstall).visibility = View.VISIBLE
}
holder.textView.visibility = View.VISIBLE
}
override fun getItemCount(): Int {
return apps.size
}
@SuppressLint("NotifyDataSetChanged")
fun updateApps(newApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
apps = newApps.toMutableList()
notifyDataSetChanged()
}
}