mirror of
https://github.com/jrpie/Launcher.git
synced 2025-02-22 22:11:27 +01:00
parent
e4b1bccf85
commit
662efd4ecb
19 changed files with 372 additions and 89 deletions
9
.idea/codeStyles/Project.xml
generated
9
.idea/codeStyles/Project.xml
generated
|
@ -8,15 +8,6 @@
|
||||||
<package name="io.ktor" alias="false" withSubpackages="true" />
|
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
|
||||||
<value>
|
|
||||||
<package name="" alias="false" withSubpackages="true" />
|
|
||||||
<package name="java" alias="false" withSubpackages="true" />
|
|
||||||
<package name="javax" alias="false" withSubpackages="true" />
|
|
||||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
|
||||||
<package name="" alias="true" withSubpackages="true" />
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
</JetCodeStyleSettings>
|
</JetCodeStyleSettings>
|
||||||
<codeStyleSettings language="XML">
|
<codeStyleSettings language="XML">
|
||||||
|
|
|
@ -41,8 +41,6 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
// minifyEnabled true
|
// minifyEnabled true
|
||||||
|
|
|
@ -32,6 +32,12 @@ enum class LauncherAction(
|
||||||
R.drawable.baseline_menu_24,
|
R.drawable.baseline_menu_24,
|
||||||
::openAppsList
|
::openAppsList
|
||||||
),
|
),
|
||||||
|
CHOOSE_FROM_FAVORITES(
|
||||||
|
"launcher:chooseFromFavorites",
|
||||||
|
R.string.list_other_list_favorites,
|
||||||
|
R.drawable.baseline_favorite_24,
|
||||||
|
{ context -> openAppsList(context, true)}
|
||||||
|
),
|
||||||
VOLUME_UP(
|
VOLUME_UP(
|
||||||
"launcher:volumeUp",
|
"launcher:volumeUp",
|
||||||
R.string.list_other_volume_up,
|
R.string.list_other_volume_up,
|
||||||
|
@ -174,12 +180,15 @@ private fun openSettings(context: Context) {
|
||||||
context.startActivity(Intent(context, SettingsActivity::class.java))
|
context.startActivity(Intent(context, SettingsActivity::class.java))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openAppsList(context: Context) {
|
fun openAppsList(context: Context, favorite: Boolean = false, hidden: Boolean = false) {
|
||||||
val intent = Intent(context, ListActivity::class.java)
|
val intent = Intent(context, ListActivity::class.java)
|
||||||
intent.putExtra("intention", ListActivity.ListActivityIntention.VIEW.toString())
|
intent.putExtra("intention", ListActivity.ListActivityIntention.VIEW.toString())
|
||||||
|
intent.putExtra("favorite", favorite)
|
||||||
|
intent.putExtra("hidden", hidden)
|
||||||
context.startActivity(intent)
|
context.startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package de.jrpie.android.launcher.apps
|
||||||
|
|
||||||
|
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.text.Regex.Companion.escapeReplacement
|
||||||
|
|
||||||
|
class AppFilter(
|
||||||
|
var search: String,
|
||||||
|
var showOnlyFavorites: Boolean = false,
|
||||||
|
var showOnlyHidden: Boolean = false
|
||||||
|
) {
|
||||||
|
operator fun invoke(apps: List<DetailedAppInfo>): List<DetailedAppInfo> {
|
||||||
|
var apps = apps
|
||||||
|
|
||||||
|
val hidden = LauncherPreferences.apps().hidden() ?: setOf()
|
||||||
|
apps = apps.filter { info -> !showOnlyHidden.xor(hidden.contains(info.app)) }
|
||||||
|
|
||||||
|
if (showOnlyFavorites) {
|
||||||
|
val favorites = LauncherPreferences.apps().favorites() ?: setOf()
|
||||||
|
apps = apps.filter { info -> favorites.contains(info.app) }
|
||||||
|
}
|
||||||
|
// normalize text for search
|
||||||
|
var allowedSpecialCharacters = search
|
||||||
|
.lowercase(Locale.ROOT)
|
||||||
|
.toCharArray()
|
||||||
|
.distinct()
|
||||||
|
.filter { c -> !c.isLetter() }
|
||||||
|
.map { c -> escapeReplacement(c.toString()) }
|
||||||
|
.fold("") { x, y -> x + y }
|
||||||
|
var disallowedCharsRegex = "[^\\p{L}$allowedSpecialCharacters]".toRegex()
|
||||||
|
|
||||||
|
fun normalize(text: String): String {
|
||||||
|
return text.lowercase(Locale.ROOT).replace(disallowedCharsRegex, "")
|
||||||
|
}
|
||||||
|
if (search.isEmpty()) {
|
||||||
|
return apps;
|
||||||
|
} else {
|
||||||
|
val r: MutableList<DetailedAppInfo> = ArrayList()
|
||||||
|
val appsSecondary: MutableList<DetailedAppInfo> = ArrayList()
|
||||||
|
val normalizedText: String = normalize(search)
|
||||||
|
for (item in apps) {
|
||||||
|
val itemLabel: String = normalize(item.label.toString())
|
||||||
|
|
||||||
|
if (itemLabel.startsWith(normalizedText)) {
|
||||||
|
r.add(item)
|
||||||
|
} else if (itemLabel.contains(normalizedText)) {
|
||||||
|
appsSecondary.add(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.addAll(appsSecondary)
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,17 @@ class AppInfo(val packageName: CharSequence, val user: Int = INVALID_USER) {
|
||||||
return "$packageName;$u"
|
return "$packageName;$u"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if(other is AppInfo) {
|
||||||
|
return other.user == user && other.packageName == packageName
|
||||||
|
}
|
||||||
|
return super.equals(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return packageName.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
fun getLauncherActivityInfo(
|
fun getLauncherActivityInfo(
|
||||||
context: Context
|
context: Context
|
||||||
): LauncherActivityInfo? {
|
): LauncherActivityInfo? {
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
package de.jrpie.android.launcher.preferences;
|
package de.jrpie.android.launcher.preferences;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import de.jrpie.android.launcher.R;
|
import de.jrpie.android.launcher.R;
|
||||||
|
import de.jrpie.android.launcher.apps.AppInfo;
|
||||||
import de.jrpie.android.launcher.preferences.theme.Background;
|
import de.jrpie.android.launcher.preferences.theme.Background;
|
||||||
import de.jrpie.android.launcher.preferences.theme.ColorTheme;
|
import de.jrpie.android.launcher.preferences.theme.ColorTheme;
|
||||||
import de.jrpie.android.launcher.preferences.theme.Font;
|
import de.jrpie.android.launcher.preferences.theme.Font;
|
||||||
import eu.jonahbauer.android.preference.annotations.Preference;
|
import eu.jonahbauer.android.preference.annotations.Preference;
|
||||||
import eu.jonahbauer.android.preference.annotations.PreferenceGroup;
|
import eu.jonahbauer.android.preference.annotations.PreferenceGroup;
|
||||||
import eu.jonahbauer.android.preference.annotations.Preferences;
|
import eu.jonahbauer.android.preference.annotations.Preferences;
|
||||||
|
import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSerializationException;
|
||||||
|
import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSerializer;
|
||||||
|
|
||||||
@Preferences(
|
@Preferences(
|
||||||
name = "de.jrpie.android.launcher.preferences.LauncherPreferences",
|
name = "de.jrpie.android.launcher.preferences.LauncherPreferences",
|
||||||
|
@ -18,6 +24,10 @@ import eu.jonahbauer.android.preference.annotations.Preferences;
|
||||||
@Preference(name = "started_time", type = long.class),
|
@Preference(name = "started_time", type = long.class),
|
||||||
@Preference(name = "version_code", type = int.class, defaultValue = "-1"),
|
@Preference(name = "version_code", type = int.class, defaultValue = "-1"),
|
||||||
}),
|
}),
|
||||||
|
@PreferenceGroup(name = "apps", prefix = "settings_apps_", suffix = "_key", value = {
|
||||||
|
@Preference(name = "favorites", type = Set.class, serializer = LauncherPreferences$Config.AppInfoSetSerializer.class),
|
||||||
|
@Preference(name = "hidden", type = Set.class, serializer = LauncherPreferences$Config.AppInfoSetSerializer.class),
|
||||||
|
}),
|
||||||
@PreferenceGroup(name = "gestures", prefix = "settings_gesture_", suffix = "_key", value = {
|
@PreferenceGroup(name = "gestures", prefix = "settings_gesture_", suffix = "_key", value = {
|
||||||
}),
|
}),
|
||||||
@PreferenceGroup(name = "general", prefix = "settings_general_", suffix = "_key", value = {
|
@PreferenceGroup(name = "general", prefix = "settings_general_", suffix = "_key", value = {
|
||||||
|
@ -53,4 +63,32 @@ import eu.jonahbauer.android.preference.annotations.Preferences;
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
public final class LauncherPreferences$Config {
|
public final class LauncherPreferences$Config {
|
||||||
|
public static class AppInfoSetSerializer implements PreferenceSerializer<Set<AppInfo>, Set<String>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> serialize(Set<AppInfo> value) throws PreferenceSerializationException {
|
||||||
|
if (value == null) return null;
|
||||||
|
|
||||||
|
var serialized = new HashSet<String>(value.size());
|
||||||
|
for (var app : value) {
|
||||||
|
serialized.add(app.serialize());
|
||||||
|
}
|
||||||
|
|
||||||
|
return serialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<AppInfo> deserialize(Set<String> value) throws PreferenceSerializationException {
|
||||||
|
if (value == null) return null;
|
||||||
|
|
||||||
|
var deserialized = new HashSet<AppInfo>(value.size());
|
||||||
|
|
||||||
|
for (var s : value) {
|
||||||
|
deserialized.add(AppInfo.Companion.deserialize(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
return deserialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ import de.jrpie.android.launcher.ui.list.other.ListFragmentOther
|
||||||
|
|
||||||
// TODO: Better solution for this intercommunication functionality (used in list-fragments)
|
// TODO: Better solution for this intercommunication functionality (used in list-fragments)
|
||||||
var intention = ListActivity.ListActivityIntention.VIEW
|
var intention = ListActivity.ListActivityIntention.VIEW
|
||||||
|
var showFavorites = false
|
||||||
|
var showHidden = false
|
||||||
var forGesture: String? = null
|
var forGesture: String? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,9 +47,24 @@ class ListActivity : AppCompatActivity(), UIObject {
|
||||||
PICK(R.string.list_title_pick) /* choose app or action to associate to a gesture */
|
PICK(R.string.list_title_pick) /* choose app or action to associate to a gesture */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
// get info about which action this activity is open for
|
||||||
|
intent.extras?.let { bundle ->
|
||||||
|
intention = bundle.getString("intention")
|
||||||
|
?.let { ListActivityIntention.valueOf(it) }
|
||||||
|
?: ListActivityIntention.VIEW
|
||||||
|
|
||||||
|
showFavorites = bundle.getBoolean("favorite") ?: false
|
||||||
|
showHidden = bundle.getBoolean("hidden") ?: false
|
||||||
|
|
||||||
|
if (intention != ListActivityIntention.VIEW)
|
||||||
|
forGesture = bundle.getString("forGesture")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initialise layout
|
// Initialise layout
|
||||||
binding = ListBinding.inflate(layoutInflater)
|
binding = ListBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
@ -105,6 +122,23 @@ class ListActivity : AppCompatActivity(), UIObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun updateTitle() {
|
||||||
|
var titleResource = intention.titleResource
|
||||||
|
if (intention == ListActivityIntention.VIEW) {
|
||||||
|
titleResource = if (showHidden) {
|
||||||
|
R.string.list_title_hidden
|
||||||
|
} else if (showFavorites) {
|
||||||
|
R.string.list_title_favorite
|
||||||
|
} else {
|
||||||
|
R.string.list_title_view
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.listHeading.text = getString(titleResource)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getTheme(): Resources.Theme {
|
override fun getTheme(): Resources.Theme {
|
||||||
return modifyTheme(super.getTheme())
|
return modifyTheme(super.getTheme())
|
||||||
}
|
}
|
||||||
|
@ -114,22 +148,13 @@ class ListActivity : AppCompatActivity(), UIObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun adjustLayout() {
|
override fun adjustLayout() {
|
||||||
// get info about which action this activity is open for
|
|
||||||
intent.extras?.let { bundle ->
|
|
||||||
intention = bundle.getString("intention")
|
|
||||||
?.let { ListActivityIntention.valueOf(it) }
|
|
||||||
?: ListActivityIntention.VIEW
|
|
||||||
|
|
||||||
if (intention != ListActivityIntention.VIEW)
|
|
||||||
forGesture = bundle.getString("forGesture")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide tabs for the "view" action
|
// Hide tabs for the "view" action
|
||||||
if (intention == ListActivityIntention.VIEW) {
|
if (intention == ListActivityIntention.VIEW) {
|
||||||
binding.listTabs.visibility = View.GONE
|
binding.listTabs.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.listHeading.text = getString(intention.titleResource)
|
updateTitle()
|
||||||
|
|
||||||
val sectionsPagerAdapter = ListSectionsPagerAdapter(this, supportFragmentManager)
|
val sectionsPagerAdapter = ListSectionsPagerAdapter(this, supportFragmentManager)
|
||||||
val viewPager: ViewPager = findViewById(R.id.list_viewpager)
|
val viewPager: ViewPager = findViewById(R.id.list_viewpager)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.os.AsyncTask
|
import android.os.AsyncTask
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -12,9 +13,11 @@ import android.widget.ImageView
|
||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import de.jrpie.android.launcher.R
|
import de.jrpie.android.launcher.R
|
||||||
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
|
import de.jrpie.android.launcher.REQUEST_CHOOSE_APP
|
||||||
import de.jrpie.android.launcher.actions.AppAction
|
import de.jrpie.android.launcher.actions.AppAction
|
||||||
|
import de.jrpie.android.launcher.apps.AppFilter
|
||||||
import de.jrpie.android.launcher.apps.AppInfo
|
import de.jrpie.android.launcher.apps.AppInfo
|
||||||
import de.jrpie.android.launcher.apps.DetailedAppInfo
|
import de.jrpie.android.launcher.apps.DetailedAppInfo
|
||||||
import de.jrpie.android.launcher.appsList
|
import de.jrpie.android.launcher.appsList
|
||||||
|
@ -24,8 +27,6 @@ import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||||
import de.jrpie.android.launcher.transformGrayscale
|
import de.jrpie.android.launcher.transformGrayscale
|
||||||
import de.jrpie.android.launcher.ui.list.ListActivity
|
import de.jrpie.android.launcher.ui.list.ListActivity
|
||||||
import de.jrpie.android.launcher.uninstallApp
|
import de.jrpie.android.launcher.uninstallApp
|
||||||
import java.util.*
|
|
||||||
import kotlin.text.Regex.Companion.escapeReplacement
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [RecyclerView] (efficient scrollable list) containing all apps on the users device.
|
* A [RecyclerView] (efficient scrollable list) containing all apps on the users device.
|
||||||
|
@ -37,13 +38,16 @@ import kotlin.text.Regex.Companion.escapeReplacement
|
||||||
*/
|
*/
|
||||||
class AppsRecyclerAdapter(
|
class AppsRecyclerAdapter(
|
||||||
val activity: Activity,
|
val activity: Activity,
|
||||||
|
val root: View,
|
||||||
private val intention: ListActivity.ListActivityIntention
|
private val intention: ListActivity.ListActivityIntention
|
||||||
= ListActivity.ListActivityIntention.VIEW,
|
= ListActivity.ListActivityIntention.VIEW,
|
||||||
private val forGesture: String? = ""
|
private val forGesture: String? = "",
|
||||||
|
private var appFilter: AppFilter = AppFilter("")
|
||||||
) :
|
) :
|
||||||
RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() {
|
RecyclerView.Adapter<AppsRecyclerAdapter.ViewHolder>() {
|
||||||
|
|
||||||
private val appsListDisplayed: MutableList<DetailedAppInfo>
|
private val appsListDisplayed: MutableList<DetailedAppInfo> = mutableListOf()
|
||||||
|
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
|
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
|
||||||
View.OnClickListener {
|
View.OnClickListener {
|
||||||
|
@ -61,6 +65,7 @@ class AppsRecyclerAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
|
override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
|
||||||
val appLabel = appsListDisplayed[i].label.toString()
|
val appLabel = appsListDisplayed[i].label.toString()
|
||||||
val appIcon = appsListDisplayed[i].icon
|
val appIcon = appsListDisplayed[i].icon
|
||||||
|
@ -106,6 +111,15 @@ class AppsRecyclerAdapter(
|
||||||
popup.menu.findItem(R.id.app_menu_delete).setVisible(false)
|
popup.menu.findItem(R.id.app_menu_delete).setVisible(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LauncherPreferences.apps().hidden()?.contains(appInfo.app) == true) {
|
||||||
|
popup.menu.findItem(R.id.app_menu_hidden).setTitle(R.string.list_app_hidden_remove)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LauncherPreferences.apps().favorites()?.contains(appInfo.app) == true) {
|
||||||
|
popup.menu.findItem(R.id.app_menu_favorite).setTitle(R.string.list_app_favorite_remove)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
popup.setOnMenuItemClickListener {
|
popup.setOnMenuItemClickListener {
|
||||||
when (it.itemId) {
|
when (it.itemId) {
|
||||||
R.id.app_menu_delete -> {
|
R.id.app_menu_delete -> {
|
||||||
|
@ -118,6 +132,53 @@ class AppsRecyclerAdapter(
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R.id.app_menu_favorite -> {
|
||||||
|
var favorites: MutableSet<AppInfo> =
|
||||||
|
LauncherPreferences.apps().favorites() ?: mutableSetOf()
|
||||||
|
|
||||||
|
Log.i("LAUNCHER", favorites.size.toString())
|
||||||
|
for (app in favorites) {
|
||||||
|
Log.i("LAUNCHER", app.serialize())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (favorites.contains(appInfo.app)) {
|
||||||
|
favorites.remove(appInfo.app)
|
||||||
|
Log.i("LAUNCHER", "Removing " + appInfo.app.serialize() + " from favorites.")
|
||||||
|
} else {
|
||||||
|
Log.i("LAUNCHER", "Adding " + appInfo.app.serialize() + " to favorites.")
|
||||||
|
favorites.add(appInfo.app)
|
||||||
|
}
|
||||||
|
Log.i("LAUNCHER", favorites.size.toString())
|
||||||
|
for (app in favorites) {
|
||||||
|
Log.i("LAUNCHER", app.serialize())
|
||||||
|
|
||||||
|
}
|
||||||
|
LauncherPreferences.apps().favorites(favorites)
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
R.id.app_menu_hidden -> {
|
||||||
|
var hidden: MutableSet<AppInfo> =
|
||||||
|
LauncherPreferences.apps().hidden() ?: mutableSetOf()
|
||||||
|
if (hidden.contains(appInfo.app)) {
|
||||||
|
hidden.remove(appInfo.app)
|
||||||
|
} else {
|
||||||
|
hidden.add(appInfo.app)
|
||||||
|
|
||||||
|
Snackbar.make(root, R.string.snackbar_app_hidden, Snackbar.LENGTH_LONG)
|
||||||
|
.setAction(R.string.undo) {
|
||||||
|
LauncherPreferences.apps().hidden(
|
||||||
|
LauncherPreferences.apps().hidden().minus(appInfo.app)
|
||||||
|
)
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
LauncherPreferences.apps().hidden(hidden)
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,9 +205,8 @@ class AppsRecyclerAdapter(
|
||||||
AsyncTask.execute { loadApps(activity.packageManager, activity) }
|
AsyncTask.execute { loadApps(activity.packageManager, activity) }
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
updateAppsList()
|
||||||
|
|
||||||
appsListDisplayed = ArrayList()
|
|
||||||
appsListDisplayed.addAll(appsList)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun selectItem(pos: Int, rect: Rect = Rect()) {
|
fun selectItem(pos: Int, rect: Rect = Rect()) {
|
||||||
|
@ -169,42 +229,13 @@ class AppsRecyclerAdapter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun updateAppsList(triggerAutoLaunch: Boolean = false) {
|
||||||
* The function [filter] is used to search elements within this [RecyclerView].
|
|
||||||
*/
|
|
||||||
fun filter(text: String) {
|
|
||||||
// normalize text for search
|
|
||||||
var allowedSpecialCharacters = text
|
|
||||||
.lowercase(Locale.ROOT)
|
|
||||||
.toCharArray()
|
|
||||||
.distinct()
|
|
||||||
.filter { c -> !c.isLetter() }
|
|
||||||
.map { c -> escapeReplacement(c.toString()) }
|
|
||||||
.fold("") { x, y -> x + y }
|
|
||||||
var disallowedCharsRegex = "[^\\p{L}$allowedSpecialCharacters]".toRegex()
|
|
||||||
|
|
||||||
fun normalize(text: String): String {
|
|
||||||
return text.lowercase(Locale.ROOT).replace(disallowedCharsRegex, "")
|
|
||||||
}
|
|
||||||
appsListDisplayed.clear()
|
appsListDisplayed.clear()
|
||||||
if (text.isEmpty()) {
|
appsListDisplayed.addAll(appFilter(appsList))
|
||||||
appsListDisplayed.addAll(appsList)
|
|
||||||
} else {
|
|
||||||
val appsSecondary: MutableList<DetailedAppInfo> = ArrayList()
|
|
||||||
val normalizedText: String = normalize(text)
|
|
||||||
for (item in appsList) {
|
|
||||||
val itemLabel: String = normalize(item.label.toString())
|
|
||||||
|
|
||||||
if (itemLabel.startsWith(normalizedText)) {
|
if (triggerAutoLaunch &&
|
||||||
appsListDisplayed.add(item)
|
appsListDisplayed.size == 1
|
||||||
} else if (itemLabel.contains(normalizedText)) {
|
&& intention == ListActivity.ListActivityIntention.VIEW
|
||||||
appsSecondary.add(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
appsListDisplayed.addAll(appsSecondary)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appsListDisplayed.size == 1 && intention == ListActivity.ListActivityIntention.VIEW
|
|
||||||
&& LauncherPreferences.functionality().searchAutoLaunch()
|
&& LauncherPreferences.functionality().searchAutoLaunch()
|
||||||
) {
|
) {
|
||||||
val info = appsListDisplayed[0]
|
val info = appsListDisplayed[0]
|
||||||
|
@ -217,4 +248,23 @@ class AppsRecyclerAdapter(
|
||||||
|
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function [setSearchString] is used to search elements within this [RecyclerView].
|
||||||
|
*/
|
||||||
|
fun setSearchString(search: String) {
|
||||||
|
appFilter.search = search
|
||||||
|
updateAppsList(true)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setShowOnlyFavorites(show: Boolean) {
|
||||||
|
appFilter.showOnlyFavorites = show
|
||||||
|
updateAppsList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setShowHiddenApps(show: Boolean) {
|
||||||
|
appFilter.showOnlyHidden = show
|
||||||
|
updateAppsList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
package de.jrpie.android.launcher.ui.list.apps
|
package de.jrpie.android.launcher.ui.list.apps
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
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 androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import de.jrpie.android.launcher.apps.AppFilter
|
||||||
import de.jrpie.android.launcher.databinding.ListAppsBinding
|
import de.jrpie.android.launcher.databinding.ListAppsBinding
|
||||||
import de.jrpie.android.launcher.openSoftKeyboard
|
import de.jrpie.android.launcher.openSoftKeyboard
|
||||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||||
|
@ -13,6 +15,8 @@ import de.jrpie.android.launcher.ui.UIObject
|
||||||
import de.jrpie.android.launcher.ui.list.ListActivity
|
import de.jrpie.android.launcher.ui.list.ListActivity
|
||||||
import de.jrpie.android.launcher.ui.list.forGesture
|
import de.jrpie.android.launcher.ui.list.forGesture
|
||||||
import de.jrpie.android.launcher.ui.list.intention
|
import de.jrpie.android.launcher.ui.list.intention
|
||||||
|
import de.jrpie.android.launcher.ui.list.showFavorites
|
||||||
|
import de.jrpie.android.launcher.ui.list.showHidden
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,6 +26,12 @@ import de.jrpie.android.launcher.ui.list.intention
|
||||||
*/
|
*/
|
||||||
class ListFragmentApps : Fragment(), UIObject {
|
class ListFragmentApps : Fragment(), UIObject {
|
||||||
private lateinit var binding: ListAppsBinding
|
private lateinit var binding: ListAppsBinding
|
||||||
|
private lateinit var appsRViewAdapter: AppsRecyclerAdapter
|
||||||
|
|
||||||
|
private var sharedPreferencesListener =
|
||||||
|
SharedPreferences.OnSharedPreferenceChangeListener { _, _ ->
|
||||||
|
appsRViewAdapter.updateAppsList()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
@ -34,13 +44,28 @@ class ListFragmentApps : Fragment(), UIObject {
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super<Fragment>.onStart()
|
super<Fragment>.onStart()
|
||||||
super<UIObject>.onStart()
|
super<UIObject>.onStart()
|
||||||
|
LauncherPreferences.getSharedPreferences()
|
||||||
|
.registerOnSharedPreferenceChangeListener(sharedPreferencesListener)
|
||||||
|
|
||||||
|
binding.listAppsCheckBoxFavorites.isChecked = showFavorites
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
LauncherPreferences.getSharedPreferences()
|
||||||
|
.unregisterOnSharedPreferenceChangeListener(sharedPreferencesListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun setOnClicks() {}
|
override fun setOnClicks() {}
|
||||||
|
|
||||||
override fun adjustLayout() {
|
override fun adjustLayout() {
|
||||||
|
|
||||||
val appsRViewAdapter = AppsRecyclerAdapter(requireActivity(), intention, forGesture)
|
appsRViewAdapter =
|
||||||
|
AppsRecyclerAdapter(
|
||||||
|
requireActivity(), binding.root, intention, forGesture,
|
||||||
|
appFilter = AppFilter("", showOnlyFavorites = showFavorites, showOnlyHidden = showHidden)
|
||||||
|
)
|
||||||
|
|
||||||
// set up the list / recycler
|
// set up the list / recycler
|
||||||
binding.listAppsRview.apply {
|
binding.listAppsRview.apply {
|
||||||
|
@ -54,17 +79,23 @@ class ListFragmentApps : Fragment(), UIObject {
|
||||||
androidx.appcompat.widget.SearchView.OnQueryTextListener {
|
androidx.appcompat.widget.SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
override fun onQueryTextSubmit(query: String): Boolean {
|
override fun onQueryTextSubmit(query: String): Boolean {
|
||||||
appsRViewAdapter.filter(query)
|
appsRViewAdapter.setSearchString(query)
|
||||||
appsRViewAdapter.selectItem(0)
|
appsRViewAdapter.selectItem(0)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: String): Boolean {
|
override fun onQueryTextChange(newText: String): Boolean {
|
||||||
appsRViewAdapter.filter(newText)
|
appsRViewAdapter.setSearchString(newText)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
binding.listAppsCheckBoxFavorites.setOnClickListener {
|
||||||
|
showFavorites = binding.listAppsCheckBoxFavorites.isChecked
|
||||||
|
appsRViewAdapter.setShowOnlyFavorites(showFavorites)
|
||||||
|
(activity as? ListActivity)?.updateTitle()
|
||||||
|
}
|
||||||
|
|
||||||
if (intention == ListActivity.ListActivityIntention.VIEW
|
if (intention == ListActivity.ListActivityIntention.VIEW
|
||||||
&& LauncherPreferences.functionality().searchAutoOpenKeyboard()
|
&& LauncherPreferences.functionality().searchAutoOpenKeyboard()
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.preference.PreferenceFragmentCompat
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
import de.jrpie.android.launcher.R
|
import de.jrpie.android.launcher.R
|
||||||
|
import de.jrpie.android.launcher.actions.openAppsList
|
||||||
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
import de.jrpie.android.launcher.preferences.LauncherPreferences
|
||||||
import de.jrpie.android.launcher.setDefaultHomeScreen
|
import de.jrpie.android.launcher.setDefaultHomeScreen
|
||||||
|
|
||||||
|
@ -65,6 +66,14 @@ class SettingsFragmentLauncher : PreferenceFragmentCompat() {
|
||||||
setDefaultHomeScreen(requireContext(), checkDefault = false)
|
setDefaultHomeScreen(requireContext(), checkDefault = false)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val hiddenApps = findPreference<androidx.preference.Preference>(
|
||||||
|
LauncherPreferences.apps().keys().hidden()
|
||||||
|
)
|
||||||
|
hiddenApps?.setOnPreferenceClickListener {
|
||||||
|
openAppsList(requireContext(), favorite = false, hidden = true)
|
||||||
|
true
|
||||||
|
}
|
||||||
updateVisibility()
|
updateVisibility()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z"/>
|
android:height="24dp"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="?android:textColor"
|
||||||
|
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z" />
|
||||||
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
|
android:height="24dp"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
|
||||||
|
<path
|
||||||
|
android:fillColor="?android:textColor"
|
||||||
|
android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z" />
|
||||||
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|
5
app/src/main/res/drawable/checkbox_favorite.xml
Normal file
5
app/src/main/res/drawable/checkbox_favorite.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/baseline_favorite_24" android:state_checked="true" />
|
||||||
|
<item android:drawable="@drawable/baseline_favorite_border_24" android:state_checked="false" />
|
||||||
|
</selector>
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/list_apps_container"
|
android:id="@+id/list_apps_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -17,21 +16,41 @@
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:fadeScrollbars="false"
|
||||||
|
android:fastScrollAlwaysVisible="true"
|
||||||
|
android:fastScrollEnabled="true"
|
||||||
android:scrollbars="vertical">
|
android:scrollbars="vertical">
|
||||||
|
<!--android:scrollbars="vertical"-->
|
||||||
|
|
||||||
</androidx.recyclerview.widget.RecyclerView>
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
<androidx.appcompat.widget.SearchView
|
<LinearLayout
|
||||||
android:id="@+id/list_apps_searchview"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="8sp"
|
android:orientation="horizontal"
|
||||||
android:layout_weight="0"
|
android:layout_margin="8dp"
|
||||||
android:iconifiedByDefault="false"
|
>
|
||||||
app:iconifiedByDefault="false"
|
|
||||||
app:queryHint="@string/list_apps_search_hint"
|
<androidx.appcompat.widget.SearchView
|
||||||
app:searchHintIcon="@drawable/baseline_search_24"
|
android:id="@+id/list_apps_searchview"
|
||||||
app:searchIcon="@drawable/baseline_search_24" />
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:iconifiedByDefault="false"
|
||||||
|
app:iconifiedByDefault="false"
|
||||||
|
app:queryHint="@string/list_apps_search_hint"
|
||||||
|
app:searchHintIcon="@drawable/baseline_search_24"
|
||||||
|
app:searchIcon="@drawable/baseline_search_24" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/list_apps_check_box_favorites"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="0"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:button="@drawable/checkbox_favorite" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -1,8 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:custom="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/tutorial_finish_container"
|
android:id="@+id/tutorial_finish_container"
|
||||||
android:paddingLeft="32sp"
|
android:paddingLeft="32sp"
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:id="@+id/app_menu_delete"
|
|
||||||
android:title="@string/list_app_delete" />
|
|
||||||
<item android:id="@+id/app_menu_info"
|
<item android:id="@+id/app_menu_info"
|
||||||
android:title="@string/list_app_info" />
|
android:title="@string/list_app_info" />
|
||||||
|
<item android:id="@+id/app_menu_favorite"
|
||||||
|
android:title="@string/list_app_favorite_add" />
|
||||||
|
<item android:id="@+id/app_menu_hidden"
|
||||||
|
android:title="@string/list_app_hidden_add" />
|
||||||
|
<item android:id="@+id/app_menu_delete"
|
||||||
|
android:title="@string/list_app_delete" />
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
@ -9,7 +9,10 @@
|
||||||
<string name="settings_internal_started_key" translatable="false">internal.started_before</string>
|
<string name="settings_internal_started_key" translatable="false">internal.started_before</string>
|
||||||
<string name="settings_internal_started_time_key" translatable="false">internal.first_startup</string>
|
<string name="settings_internal_started_time_key" translatable="false">internal.first_startup</string>
|
||||||
<string name="settings_internal_version_code_key" translatable="false">internal.version_code</string>
|
<string name="settings_internal_version_code_key" translatable="false">internal.version_code</string>
|
||||||
<string name="settings_general_choose_home_screen_key" translatable="false">general.select_launcher</string>
|
<string name="settings_apps_favorites_key" translatable="false">apps.favorites</string>
|
||||||
|
<string name="settings_apps_hidden_key" translatable="false">apps.hidden</string>
|
||||||
|
|
||||||
|
<string name="settings_general_choose_home_screen_key" translatable="false">general.select_launcher</string>
|
||||||
<!--
|
<!--
|
||||||
-
|
-
|
||||||
- Settings : Gestures
|
- Settings : Gestures
|
||||||
|
|
|
@ -114,6 +114,9 @@
|
||||||
|
|
||||||
<string name="settings_launcher_sensitivity">Sensitivity</string>
|
<string name="settings_launcher_sensitivity">Sensitivity</string>
|
||||||
|
|
||||||
|
<string name="settings_launcher_section_apps">Apps</string>
|
||||||
|
<string name="settings_apps_hidden">Hidden apps</string>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
-
|
-
|
||||||
- Settings : Meta
|
- Settings : Meta
|
||||||
|
@ -144,6 +147,8 @@
|
||||||
-
|
-
|
||||||
-->
|
-->
|
||||||
<string name="list_title_view">All Apps</string>
|
<string name="list_title_view">All Apps</string>
|
||||||
|
<string name="list_title_favorite">Favorite Apps</string>
|
||||||
|
<string name="list_title_hidden">Hidden Apps</string>
|
||||||
<string name="list_title_pick">Choose App</string>
|
<string name="list_title_pick">Choose App</string>
|
||||||
|
|
||||||
<string name="list_tab_app">Apps</string>
|
<string name="list_tab_app">Apps</string>
|
||||||
|
@ -151,6 +156,10 @@
|
||||||
|
|
||||||
<string name="list_app_delete">Uninstall</string>
|
<string name="list_app_delete">Uninstall</string>
|
||||||
<string name="list_app_info">App Info</string>
|
<string name="list_app_info">App Info</string>
|
||||||
|
<string name="list_app_favorite_add">Add to favorites</string>
|
||||||
|
<string name="list_app_favorite_remove">Remove from favorites</string>
|
||||||
|
<string name="list_app_hidden_add">Hide</string>
|
||||||
|
<string name="list_app_hidden_remove">Show</string>
|
||||||
|
|
||||||
<string name="list_removed">Removed the selected application</string>
|
<string name="list_removed">Removed the selected application</string>
|
||||||
<string name="list_not_removed">Unable to remove application</string>
|
<string name="list_not_removed">Unable to remove application</string>
|
||||||
|
@ -159,6 +168,7 @@
|
||||||
|
|
||||||
<string name="list_other_settings">Launcher Settings</string>
|
<string name="list_other_settings">Launcher Settings</string>
|
||||||
<string name="list_other_list">All Applications</string>
|
<string name="list_other_list">All Applications</string>
|
||||||
|
<string name="list_other_list_favorites">Favorite Applications</string>
|
||||||
<string name="list_other_volume_up">Music: Louder</string>
|
<string name="list_other_volume_up">Music: Louder</string>
|
||||||
<string name="list_other_volume_down">Music: Quieter</string>
|
<string name="list_other_volume_down">Music: Quieter</string>
|
||||||
<string name="list_other_track_next">Music: Next</string>
|
<string name="list_other_track_next">Music: Next</string>
|
||||||
|
@ -195,4 +205,6 @@
|
||||||
<string name="settings">Settings</string>
|
<string name="settings">Settings</string>
|
||||||
<string name="ic_menu_alt">More options</string>
|
<string name="ic_menu_alt">More options</string>
|
||||||
<string name="alert_cant_expand_notifications_panel">Error: Can\'t expand status bar.\nThis action is using functionality that is not part of the published Android API. Unfortunately, it does not seem to work on your device.</string>
|
<string name="alert_cant_expand_notifications_panel">Error: Can\'t expand status bar.\nThis action is using functionality that is not part of the published Android API. Unfortunately, it does not seem to work on your device.</string>
|
||||||
|
<string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string>
|
||||||
|
<string name="undo">Undo</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -97,6 +97,17 @@
|
||||||
android:title="@string/settings_enabled_gestures_edge_swipe"/>
|
android:title="@string/settings_enabled_gestures_edge_swipe"/>
|
||||||
|
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="@string/settings_launcher_section_apps"
|
||||||
|
app:allowDividerAbove="false">
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="@string/settings_apps_hidden_key"
|
||||||
|
android:title="@string/settings_apps_hidden"
|
||||||
|
/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/settings_launcher_section_display"
|
android:title="@string/settings_launcher_section_display"
|
||||||
|
|
Loading…
Add table
Reference in a new issue