mirror of
https://github.com/He4eT/yamf_launcher.git
synced 2026-05-05 01:47:24 +00:00
Fixed an issue with updating apps (and brought back old recycler updating logic tot ry out)
This commit is contained in:
parent
2a0be96ee6
commit
84e9ee2280
6 changed files with 186 additions and 36 deletions
|
|
@ -61,6 +61,7 @@ class AppActionMenu {
|
|||
activity.startActivity(intent)
|
||||
|
||||
animations.fadeViewOut(actionMenu, 100)
|
||||
|
||||
textView.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package eu.ottop.yamlauncher
|
||||
|
||||
import android.R.color
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.content.pm.LauncherApps
|
||||
import android.graphics.BlendMode
|
||||
import android.graphics.BlendModeColorFilter
|
||||
import android.graphics.Color
|
||||
|
|
@ -27,7 +27,8 @@ class AppMenuAdapter(
|
|||
var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
|
||||
private val itemClickListener: OnItemClickListener,
|
||||
private val shortcutListener: OnShortcutListener,
|
||||
private val itemLongClickListener: OnItemLongClickListener
|
||||
private val itemLongClickListener: OnItemLongClickListener,
|
||||
private val launcherApps: LauncherApps
|
||||
) :
|
||||
RecyclerView.Adapter<AppMenuAdapter.AppViewHolder>() {
|
||||
|
||||
|
|
@ -151,17 +152,38 @@ class AppMenuAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
val appInfo = app.first.activityInfo.applicationInfo
|
||||
holder.textView.setTextColor(Color.parseColor(preferences?.getString("textColor", "#FFF3F3F3")))
|
||||
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)
|
||||
val appUtils = AppUtils()
|
||||
var appInfo = appUtils.getAppInfo(
|
||||
launcherApps,
|
||||
app.first.applicationInfo.packageName,
|
||||
app.second.second
|
||||
)
|
||||
|
||||
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.setTextColor(Color.parseColor(preferences?.getString("textColor", "#FFF3F3F3")))
|
||||
var appLabel: CharSequence = ""
|
||||
appLabel = appInfo?.loadLabel(activity.packageManager) ?: "Removing..."
|
||||
|
||||
println(appLabel)
|
||||
|
||||
if (appInfo != null) {
|
||||
holder.textView.text = sharedPreferenceManager.getAppName(
|
||||
activity,
|
||||
appInfo.packageName,
|
||||
app.second.second,
|
||||
appLabel
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
else {holder.textView.text = appLabel}
|
||||
|
||||
holder.textView.visibility = View.VISIBLE
|
||||
}
|
||||
|
|
@ -170,9 +192,28 @@ class AppMenuAdapter(
|
|||
return apps.size
|
||||
}
|
||||
|
||||
fun addApp(position: Int, app: Pair<LauncherActivityInfo, Pair<UserHandle, Int>>) {
|
||||
apps.add(position, app)
|
||||
}
|
||||
|
||||
fun removeApp(position: Int) {
|
||||
apps.removeAt(position)
|
||||
}
|
||||
|
||||
fun updateApp(position: Int, app: Pair<LauncherActivityInfo, Pair<UserHandle, Int>>) {
|
||||
apps[position] = app
|
||||
}
|
||||
|
||||
fun moveApp(position: Int, newPosition: Int) {
|
||||
val app = apps.removeAt(position)
|
||||
apps.add(newPosition, app)
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun updateApps(newApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
|
||||
apps = newApps.toMutableList()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package eu.ottop.yamlauncher
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.content.pm.LauncherApps
|
||||
import android.os.UserHandle
|
||||
|
|
@ -10,9 +11,9 @@ class AppUtils {
|
|||
|
||||
private val sharedPreferenceManager = SharedPreferenceManager()
|
||||
|
||||
fun getInstalledApps(activity: Activity): List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>> {
|
||||
fun getInstalledApps(activity: Activity, launcherApps: LauncherApps): List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>> {
|
||||
val allApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
|
||||
val launcherApps = activity.getSystemService(AppCompatActivity.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
|
||||
for (i in launcherApps.profiles.indices) {
|
||||
launcherApps.getActivityList(null, launcherApps.profiles[i]).forEach { app ->
|
||||
if (!sharedPreferenceManager.isAppHidden(activity, app.applicationInfo.packageName, i) && app.applicationInfo.packageName != activity.applicationInfo.packageName) {
|
||||
|
|
@ -21,7 +22,7 @@ class AppUtils {
|
|||
}
|
||||
}
|
||||
return allApps.sortedBy {
|
||||
sharedPreferenceManager.getAppName(activity, it.first.applicationInfo.packageName,it.second.second, activity.packageManager.getApplicationLabel(it.first.applicationInfo)).toString().lowercase()
|
||||
sharedPreferenceManager.getAppName(activity, it.first.applicationInfo.packageName,it.second.second, it.first.applicationInfo.loadLabel(activity.packageManager)).toString().lowercase()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -40,4 +41,15 @@ class AppUtils {
|
|||
sharedPreferenceManager.getAppName(activity, it.first.applicationInfo.packageName,it.second.second, activity.packageManager.getApplicationLabel(it.first.applicationInfo)).toString().lowercase()
|
||||
}
|
||||
}
|
||||
|
||||
fun getAppInfo(
|
||||
launcherApps: LauncherApps,
|
||||
packageName: String,
|
||||
profile: Int
|
||||
): ApplicationInfo? {
|
||||
|
||||
return launcherApps.getActivityList(
|
||||
packageName, launcherApps.profiles[profile]
|
||||
).firstOrNull()?.applicationInfo
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,9 @@ package eu.ottop.yamlauncher
|
|||
|
||||
import android.app.Activity
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.content.pm.LauncherActivityInfo
|
||||
import android.content.pm.LauncherApps
|
||||
import android.os.Bundle
|
||||
import android.os.UserHandle
|
||||
import android.text.Editable
|
||||
|
|
@ -13,6 +15,7 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat.getSystemService
|
||||
import androidx.fragment.app.setFragmentResult
|
||||
import androidx.preference.Preference
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
|
@ -27,6 +30,7 @@ class GestureAppsFragment : Fragment(), GestureAppsAdapter.OnItemClickListener {
|
|||
private val sharedPreferenceManager = SharedPreferenceManager()
|
||||
private var stringUtils = StringUtils()
|
||||
private val appUtils = AppUtils()
|
||||
private lateinit var launcherApps: LauncherApps
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
|
@ -43,9 +47,11 @@ class GestureAppsFragment : Fragment(), GestureAppsAdapter.OnItemClickListener {
|
|||
|
||||
withContext(Dispatchers.Default) {
|
||||
|
||||
launcherApps = requireContext().getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||
|
||||
adapter = GestureAppsAdapter(
|
||||
requireContext(),
|
||||
appUtils.getInstalledApps(activity as Activity).toMutableList(),
|
||||
appUtils.getInstalledApps(activity as Activity, launcherApps).toMutableList(),
|
||||
this@GestureAppsFragment
|
||||
)
|
||||
}
|
||||
|
|
@ -93,7 +99,7 @@ class GestureAppsFragment : Fragment(), GestureAppsAdapter.OnItemClickListener {
|
|||
|
||||
val cleanQuery = stringUtils.cleanString(query)
|
||||
val newFilteredApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
|
||||
val updatedApps = appUtils.getInstalledApps(requireActivity())
|
||||
val updatedApps = appUtils.getInstalledApps(requireActivity(), launcherApps)
|
||||
|
||||
getFilteredApps(cleanQuery, newFilteredApps, updatedApps)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import android.os.Bundle
|
|||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.UserHandle
|
||||
import android.provider.MediaStore
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.GestureDetector
|
||||
|
|
@ -25,11 +24,8 @@ import android.view.View
|
|||
import android.view.View.TEXT_ALIGNMENT_CENTER
|
||||
import android.view.View.TEXT_ALIGNMENT_TEXT_END
|
||||
import android.view.View.TEXT_ALIGNMENT_TEXT_START
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextClock
|
||||
import android.widget.TextView
|
||||
|
|
@ -37,8 +33,6 @@ import android.widget.Toast
|
|||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.marginLeft
|
||||
|
|
@ -425,7 +419,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
private fun setupApps() {
|
||||
handleListItems()
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
installedApps = appUtils.getInstalledApps(this@MainActivity)
|
||||
installedApps = appUtils.getInstalledApps(this@MainActivity, launcherApps)
|
||||
val newApps = installedApps.toMutableList()
|
||||
|
||||
setupRecyclerView(newApps)
|
||||
|
|
@ -499,7 +493,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
}
|
||||
|
||||
private suspend fun setupRecyclerView(newApps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
|
||||
adapter = AppMenuAdapter(this@MainActivity, newApps, this@MainActivity, this@MainActivity, this@MainActivity)
|
||||
adapter = AppMenuAdapter(this@MainActivity, newApps, this@MainActivity, this@MainActivity, this@MainActivity, launcherApps)
|
||||
appMenuLinearLayoutManager.stackFromEnd = true
|
||||
recyclerView = findViewById(R.id.recycler_view)
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
@ -560,7 +554,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
|
||||
val cleanQuery = stringUtils.cleanString(query)
|
||||
val newFilteredApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
|
||||
val updatedApps = appUtils.getInstalledApps(this@MainActivity)
|
||||
val updatedApps = appUtils.getInstalledApps(this@MainActivity, launcherApps)
|
||||
|
||||
getFilteredApps(cleanQuery, newFilteredApps, updatedApps)
|
||||
|
||||
|
|
@ -625,7 +619,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
}, 100)
|
||||
handler.postDelayed({
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
refreshAppMenu()
|
||||
|
||||
|
||||
try {
|
||||
withContext(Dispatchers.Main) {
|
||||
|
|
@ -711,18 +705,27 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
}
|
||||
|
||||
suspend fun refreshAppMenu() {
|
||||
try {
|
||||
val updatedApps = appUtils.getInstalledApps(this@MainActivity, launcherApps)
|
||||
val changes = detectChanges(installedApps, updatedApps)
|
||||
installedApps = updatedApps
|
||||
withContext(Dispatchers.Main) {
|
||||
applyChanges(changes, installedApps)
|
||||
}
|
||||
}
|
||||
catch (_: UninitializedPropertyAccessException) {
|
||||
}
|
||||
/*
|
||||
try {
|
||||
val updatedApps = appUtils.getInstalledApps(this@MainActivity)
|
||||
val updatedApps = appUtils.getInstalledApps(this@MainActivity, launcherApps)
|
||||
println("update running")
|
||||
if (!listsEqual(installedApps, updatedApps)) {
|
||||
withContext(Dispatchers.Main) {
|
||||
updateMenu(updatedApps)
|
||||
}
|
||||
installedApps = updatedApps
|
||||
withContext(Dispatchers.Main) {
|
||||
updateMenu(updatedApps)
|
||||
}
|
||||
installedApps = updatedApps
|
||||
}
|
||||
catch (_: UninitializedPropertyAccessException) {
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -799,7 +802,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
searchView.textAlignment = View.TEXT_ALIGNMENT_VIEW_START
|
||||
}
|
||||
"center" -> {
|
||||
searchView.textAlignment = View.TEXT_ALIGNMENT_CENTER
|
||||
searchView.textAlignment = TEXT_ALIGNMENT_CENTER
|
||||
}
|
||||
"right" -> {
|
||||
searchView.textAlignment = View.TEXT_ALIGNMENT_VIEW_END
|
||||
|
|
@ -902,4 +905,91 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
|
|||
false
|
||||
}
|
||||
}
|
||||
|
||||
fun detectChanges(oldList: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>, newList: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>): List<Change> {
|
||||
val changes = mutableListOf<Change>()
|
||||
val removalChanges = mutableListOf<Change>()
|
||||
val oldSet = oldList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet()
|
||||
val newSet = newList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet()
|
||||
|
||||
// Detect removals
|
||||
oldList.forEachIndexed { index, oldItem ->
|
||||
if (!newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
|
||||
removalChanges.add(Change(ChangeType.REMOVE, index))
|
||||
}
|
||||
}
|
||||
|
||||
// Detect insertions
|
||||
newList.forEachIndexed { index, newItem ->
|
||||
if (!oldSet.contains(Pair(newItem.first.applicationInfo.packageName, newItem.second.second))) {
|
||||
changes.add(Change(ChangeType.INSERT, index))
|
||||
}
|
||||
}
|
||||
|
||||
oldList.forEachIndexed { index, oldItem ->
|
||||
if (newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
|
||||
val newIndex = newList.indexOfFirst { it.first.applicationInfo.packageName == oldItem.first.applicationInfo.packageName && it.second.second == oldItem.second.second }
|
||||
if (oldItem.first.componentName != newList[newIndex].first.componentName) {
|
||||
changes.add(Change(ChangeType.UPDATE, index))
|
||||
}
|
||||
if (index != newIndex) {
|
||||
changes.add(Change(ChangeType.MOVE, index))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
changes.addAll(removalChanges.reversed())
|
||||
|
||||
return changes
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun applyChanges(changes: List<Change>, updatedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
|
||||
changes.forEach { change ->
|
||||
when (change.type) {
|
||||
ChangeType.INSERT -> {
|
||||
insertItem(change.position, updatedApps[change.position])
|
||||
}
|
||||
ChangeType.REMOVE -> {
|
||||
try {
|
||||
removeItem(change.position)
|
||||
}
|
||||
catch (_: IndexOutOfBoundsException) {
|
||||
}
|
||||
}
|
||||
ChangeType.UPDATE -> {
|
||||
updateItem(change.position, updatedApps[change.position])
|
||||
}
|
||||
|
||||
ChangeType.MOVE -> {
|
||||
adapter?.updateApps(updatedApps)
|
||||
adapter?.notifyDataSetChanged()
|
||||
println("moved")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun insertItem(position: Int, app: Pair<LauncherActivityInfo, Pair<UserHandle, Int>>) {
|
||||
adapter?.addApp(position, app)
|
||||
adapter?.notifyItemInserted(position)
|
||||
}
|
||||
private fun removeItem(position: Int) {
|
||||
adapter?.removeApp(position)
|
||||
adapter?.notifyItemRemoved(position)
|
||||
}
|
||||
|
||||
private fun updateItem(position: Int, app: Pair<LauncherActivityInfo, Pair<UserHandle, Int>>) {
|
||||
adapter?.updateApp(position, app)
|
||||
adapter?.notifyItemChanged(position)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class Change(val type: ChangeType, val position: Int, val newPosition: Int = 0)
|
||||
|
||||
enum class ChangeType {
|
||||
INSERT, REMOVE, UPDATE, MOVE
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@
|
|||
<SwitchPreference
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:defaultValue="true"
|
||||
android:defaultValue="false"
|
||||
android:title="Swipe Left"
|
||||
app:key="leftSwipe" />
|
||||
<Preference
|
||||
|
|
@ -136,7 +136,7 @@
|
|||
<SwitchPreference
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:defaultValue="true"
|
||||
android:defaultValue="false"
|
||||
android:title="Swipe Right"
|
||||
app:key="rightSwipe" />
|
||||
<Preference
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue