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 import androidx.recyclerview.widget.RecyclerView
class AppMenuAdapter( class AppMenuAdapter(
private val activity: MainActivity, private val activity: Context,
var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>, var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
private val itemClickListener: OnItemClickListener, private val itemClickListener: OnItemClickListener,
private val shortcutListener: OnShortcutListener, private val shortcutListener: OnShortcutListener,

View file

@ -14,43 +14,22 @@ import android.widget.FrameLayout
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.FragmentActivity
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlin.time.Duration.Companion.seconds
class HiddenAppsAdapter( class HiddenAppsAdapter(
private val activity: Context, private val activity: Context,
var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>, var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
private val itemClickListener: OnItemClickListener, private val itemClickListener: OnItemClickListener
private val shortcutListener: OnShortcutListener,
private val itemLongClickListener: OnItemLongClickListener
) : ) :
RecyclerView.Adapter<HiddenAppsAdapter.AppViewHolder>() { RecyclerView.Adapter<HiddenAppsAdapter.AppViewHolder>() {
var menuMode: String = "app"
var shortcutTextView: TextView? = null
private val sharedPreferenceManager = SharedPreferenceManager() private val sharedPreferenceManager = SharedPreferenceManager()
private var preferences = PreferenceManager.getDefaultSharedPreferences(activity) private var preferences = PreferenceManager.getDefaultSharedPreferences(activity)
interface OnItemClickListener { interface OnItemClickListener {
fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) fun onItemClick(appInfo: LauncherActivityInfo, profile: Int)
}
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) { inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@ -67,31 +46,7 @@ class HiddenAppsAdapter(
textView.setOnClickListener { textView.setOnClickListener {
val position = bindingAdapterPosition val position = bindingAdapterPosition
val app = apps[position].first val app = apps[position].first
if (menuMode == "shortcut") { itemClickListener.onItemClick(app, apps[position].second.second)
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
}
} }
} }

View file

@ -1,18 +1,18 @@
package eu.ottop.yamlauncher package eu.ottop.yamlauncher
import android.app.Activity import android.app.Activity
import android.app.AlertDialog
import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherActivityInfo
import android.os.Bundle import android.os.Bundle
import android.os.UserHandle import android.os.UserHandle
import android.text.Editable
import android.text.TextWatcher
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.LinearLayout import android.widget.EditText
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
// TODO: Rename parameter arguments, choose names that match // TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER // 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 * Use the [HiddenAppsFragment.newInstance] factory method to
* create an instance of this fragment. * 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 // TODO: Rename and change types of parameters
private var param1: String? = null private var param1: String? = null
private var param2: String? = null private var param2: String? = null
private val appUtils = AppUtils() private val appUtils = AppUtils()
private val sharedPreferenceManager = SharedPreferenceManager()
private var adapter: HiddenAppsAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -50,13 +52,100 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, Hi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) 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 recyclerView = view.findViewById<RecyclerView>(R.id.hidden_app_recycler)
val appMenuEdgeFactory = AppMenuEdgeFactory(requireActivity()) val appMenuEdgeFactory = AppMenuEdgeFactory(requireActivity())
recyclerView.edgeEffectFactory = appMenuEdgeFactory recyclerView.edgeEffectFactory = appMenuEdgeFactory
recyclerView.adapter = adapter recyclerView.adapter = adapter
recyclerView.scrollToPosition(0) 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 { companion object {
@ -79,29 +168,10 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener, Hi
} }
} }
override fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) { override fun onItemClick(appInfo: LauncherActivityInfo, profile: Int) {
TODO("Not yet implemented") 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()
}
}