Rewriting the app into a single activity is in progress

This commit is contained in:
ottoptj 2024-05-22 00:35:28 +03:00
commit 1f0a91e2df
5 changed files with 542 additions and 163 deletions

View file

@ -17,6 +17,7 @@ import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.AppCompatButton import androidx.appcompat.widget.AppCompatButton
import eu.ottop.yamlauncher.databinding.ActivityAppMenuBinding import eu.ottop.yamlauncher.databinding.ActivityAppMenuBinding
import eu.ottop.yamlauncher.databinding.ActivityMainBinding
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -26,9 +27,9 @@ class AppActionMenu {
private val appUtils = AppUtils() private val appUtils = AppUtils()
fun setActionListeners( fun setActionListeners(
activity: AppMenuActivity, activity: MainActivity,
uiScope: CoroutineScope, uiScope: CoroutineScope,
binding: ActivityAppMenuBinding, binding: ActivityMainBinding,
textView: TextView, textView: TextView,
editLayout: LinearLayout, editLayout: LinearLayout,
actionMenu: View, actionMenu: View,

View file

@ -15,26 +15,24 @@ import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import eu.ottop.yamlauncher.databinding.ActivityAppMenuBinding import eu.ottop.yamlauncher.databinding.ActivityAppMenuBinding
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, AppMenuAdapter.OnShortcutListener, AppMenuAdapter.OnItemLongClickListener { class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, AppMenuAdapter.OnShortcutListener, AppMenuAdapter.OnItemLongClickListener {
/*
private lateinit var binding: ActivityAppMenuBinding private lateinit var binding: ActivityAppMenuBinding
private lateinit var recyclerView: RecyclerView private lateinit var recyclerView: RecyclerView
private lateinit var searchView: EditText private lateinit var searchView: EditText
private lateinit var adapter: AppMenuAdapter private lateinit var adapter: AppMenuAdapter
private lateinit var filteredApps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
private var job: Job? = null private var job: Job? = null
private var appActionMenu = AppActionMenu() private var appActionMenu = AppActionMenu()
private lateinit var launcherApps: LauncherApps private lateinit var launcherApps: LauncherApps
@ -79,14 +77,19 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
recyclerView = findViewById(R.id.recycler_view) recyclerView = findViewById(R.id.recycler_view)
recyclerView.scrollToPosition(0) recyclerView.scrollToPosition(0)
installedApps = currentApps installedApps = currentApps
filteredApps = mutableListOf()
filteredApps.addAll(installedApps)
val newApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>() val newApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
newApps.addAll(installedApps) newApps.addAll(installedApps)
adapter = AppMenuAdapter(this@AppMenuActivity, newApps, this, this,this, menuMode) adapter = AppMenuAdapter(this@AppMenuActivity, newApps, this, this,this, menuMode)
recyclerView.adapter = adapter recyclerView.adapter = adapter
setupSearch() setupSearch()
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
finish()
}
})
} }
override fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) { override fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) {
@ -218,7 +221,6 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
private fun startTask() { private fun startTask() {
job = CoroutineScope(Dispatchers.Default).launch { job = CoroutineScope(Dispatchers.Default).launch {
while (true) { while (true) {
ensureActive()
manualRefresh() manualRefresh()
delay(5000) delay(5000)
} }
@ -317,5 +319,32 @@ class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener,
data class Change(val type: ChangeType, val position: Int, val newPosition: Int = 0) data class Change(val type: ChangeType, val position: Int, val newPosition: Int = 0)
enum class ChangeType { enum class ChangeType {
INSERT, REMOVE, UPDATE INSERT, REMOVE, UPDATE*/
override fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) {
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")
}
override fun onShortcut(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
textView: TextView,
userProfile: Int,
shortcutView: TextView
) {
TODO("Not yet implemented")
}
} }

View file

@ -14,15 +14,17 @@ import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.AppCompatButton import androidx.appcompat.widget.AppCompatButton
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
class AppMenuAdapter( class AppMenuAdapter(
private val activity: AppMenuActivity, private val activity: FragmentActivity,
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,
private val itemLongClickListener: OnItemLongClickListener, private val itemLongClickListener: OnItemLongClickListener,
private val menuMode: String private val menuMode: String = "app",
private val shortcutTextView: TextView? = null
) : ) :
RecyclerView.Adapter<AppMenuAdapter.AppViewHolder>() { RecyclerView.Adapter<AppMenuAdapter.AppViewHolder>() {
@ -33,7 +35,7 @@ class AppMenuAdapter(
} }
interface OnShortcutListener { interface OnShortcutListener {
fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int) fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int, shortcutView: TextView)
} }
interface OnItemLongClickListener { interface OnItemLongClickListener {
@ -62,7 +64,7 @@ class AppMenuAdapter(
val position = bindingAdapterPosition val position = bindingAdapterPosition
val app = apps[position].first val app = apps[position].first
if (menuMode == "shortcut") { if (menuMode == "shortcut") {
shortcutListener.onShortcut(app, apps[position].second.first, textView, apps[position].second.second) shortcutListener.onShortcut(app, apps[position].second.first, textView, apps[position].second.second, shortcutTextView!!)
} }
else if (menuMode == "app") { else if (menuMode == "app") {
itemClickListener.onItemClick(app, apps[position].second.first) itemClickListener.onItemClick(app, apps[position].second.first)

View file

@ -5,27 +5,43 @@ import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
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 android.util.Log
import android.view.GestureDetector import android.view.GestureDetector
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.view.children import androidx.core.view.children
import androidx.recyclerview.widget.RecyclerView
import eu.ottop.yamlauncher.databinding.ActivityMainBinding import eu.ottop.yamlauncher.databinding.ActivityMainBinding
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.math.abs import kotlin.math.abs
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, AppMenuAdapter.OnShortcutListener, AppMenuAdapter.OnItemLongClickListener {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private lateinit var gestureDetector: GestureDetector private lateinit var gestureDetector: GestureDetector
private lateinit var launcherApps: LauncherApps private lateinit var launcherApps: LauncherApps
private lateinit var installedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>> private lateinit var installedApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
private lateinit var recyclerView: RecyclerView
private lateinit var searchView: EditText
private lateinit var adapter: AppMenuAdapter
private var job: Job? = null
private var appActionMenu = AppActionMenu()
private val sharedPreferenceManager = SharedPreferenceManager() private val sharedPreferenceManager = SharedPreferenceManager()
private val appUtils = AppUtils() private val appUtils = AppUtils()
@ -36,9 +52,6 @@ class MainActivity : AppCompatActivity() {
setSupportActionBar(null) setSupportActionBar(null)
launcherApps = getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps launcherApps = getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
CoroutineScope(Dispatchers.Default).launch {
installedApps = appUtils.getInstalledApps(this@MainActivity)
}
for (i in findViewById<LinearLayout>(R.id.shortcuts).children) { for (i in findViewById<LinearLayout>(R.id.shortcuts).children) {
@ -74,35 +87,122 @@ class MainActivity : AppCompatActivity() {
} }
i.setOnLongClickListener { i.setOnLongClickListener {
AppMenuActivity.start(this@MainActivity, installedApps, "shortcut") { newText -> binding.homeView.visibility = View.GONE
if (newText.first.second != 0) { val newApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(resources, R.drawable.ic_work_app, null),null,null,null) newApps.addAll(installedApps)
} adapter = AppMenuAdapter(this@MainActivity, newApps, this@MainActivity, this@MainActivity, this@MainActivity, "shortcut", i)
else { recyclerView.adapter = adapter
textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(resources, R.drawable.ic_empty, null),null,null,null) binding.appView.visibility = View.VISIBLE
}
textView.text = newText.first.first
i.setOnClickListener {
val mainActivity = launcherApps.getActivityList(newText.second.first.applicationInfo.packageName, newText.second.second).firstOrNull()
if (mainActivity != null) {
launcherApps.startMainActivity(mainActivity.componentName, newText.second.second, null, null)
} else {
Toast.makeText(this, "Cannot launch app", Toast.LENGTH_SHORT).show()
}
}
sharedPreferenceManager.setShortcut(this, textView, newText.second.first.applicationInfo.packageName, newText.first.second)
}
return@setOnLongClickListener true return@setOnLongClickListener true
} }}
}
gestureDetector = GestureDetector(this, GestureListener()) gestureDetector = GestureDetector(this, GestureListener())
//Experimental
CoroutineScope(Dispatchers.Default).launch {
installedApps = appUtils.getInstalledApps(this@MainActivity)
recyclerView = findViewById(R.id.recycler_view)
recyclerView.scrollToPosition(0)
searchView = findViewById(R.id.searchView)
setupSearch()
}
} }
private fun setupSearch() {
binding.root.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom ->
if (bottom - top > oldBottom - oldTop) {
searchView.clearFocus()
if (searchView.text.isNullOrEmpty()) {
job?.cancel()
startTask()
}
}
else {
job?.cancel()
}
}
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) {
filterItems(searchView.text.toString())
}
override fun afterTextChanged(s: Editable?) {
}
})
}
private fun filterItems(query: String?) {
CoroutineScope(Dispatchers.Default).launch {
val cleanQuery = query?.clean()
val newFilteredApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
val updatedApps = appUtils.getInstalledApps(this@MainActivity)
if (cleanQuery.isNullOrEmpty()) {
manualRefresh()
newFilteredApps.addAll(installedApps)
} else {
updatedApps.forEach {
val cleanItemText = sharedPreferenceManager.getAppName(this@MainActivity, it.first.applicationInfo.packageName, it.second.second, it.first.applicationInfo.loadLabel(packageManager)).toString().clean()
if (cleanItemText.contains(cleanQuery, ignoreCase = true)) {
newFilteredApps.add(it)
}
}
}
val changes = detectChanges(installedApps, newFilteredApps)
installedApps = newFilteredApps
withContext(Dispatchers.Main) {
applyChanges(changes, installedApps)
}
}
}
private fun String.clean(): String {
return this.replace("[^a-zA-Z0-9]".toRegex(), "")
}
override fun onStop() {
super.onStop()
job?.cancel()
}
override fun onDestroy() {
super.onDestroy()
job?.cancel()
}
override fun onStart() {
super.onStart()
startTask()
// Keyboard is sometimes open when going back to the app, so close it.
val imm =
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.root.windowToken, 0)
}
private fun startTask() {
job = CoroutineScope(Dispatchers.Default).launch {
while (true) {
manualRefresh()
delay(5000)
}
}
}
override fun onTouchEvent(event: MotionEvent): Boolean { override fun onTouchEvent(event: MotionEvent): Boolean {
gestureDetector.onTouchEvent(event) gestureDetector.onTouchEvent(event)
@ -134,9 +234,178 @@ class MainActivity : AppCompatActivity() {
} }
fun openAppMenuActivity() { fun openAppMenuActivity() {
AppMenuActivity.start(this, installedApps) { //AppMenuActivity.start(this, installedApps) {
//}
binding.homeView.visibility = View.GONE
val newApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
newApps.addAll(installedApps)
adapter = AppMenuAdapter(this@MainActivity, newApps, this@MainActivity, this@MainActivity, this@MainActivity, "app")
recyclerView.adapter = adapter
binding.appView.visibility = View.VISIBLE
}
override fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle) {
val mainActivity = launcherApps.getActivityList(appInfo.applicationInfo.packageName, userHandle).firstOrNull()
if (mainActivity != null) {
launcherApps.startMainActivity(mainActivity.componentName, userHandle, null, null)
} else {
Toast.makeText(this, "Cannot launch app", Toast.LENGTH_SHORT).show()
} }
} }
override fun onShortcut(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
textView: TextView,
userProfile: Int,
shortcutView: TextView
) {
if (userProfile != 0) {
shortcutView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(resources, R.drawable.ic_work_app, null),null,null,null)
}
else {
shortcutView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(resources, R.drawable.ic_empty, null),null,null,null)
}
shortcutView.text = textView.text.toString()
shortcutView.setOnClickListener {
val mainActivity = launcherApps.getActivityList(appInfo.applicationInfo.packageName, userHandle).firstOrNull()
if (mainActivity != null) {
launcherApps.startMainActivity(mainActivity.componentName, userHandle, null, null)
} else {
Toast.makeText(this, "Cannot launch app", Toast.LENGTH_SHORT).show()
}
}
sharedPreferenceManager.setShortcut(this, shortcutView, appInfo.applicationInfo.packageName, userProfile)
binding.appView.visibility = View.GONE
binding.homeView.visibility = View.VISIBLE
}
override fun onItemLongClick(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
userProfile: Int,
textView: TextView,
actionMenuLayout: LinearLayout,
editView: LinearLayout,
position: Int
) {
textView.visibility = View.INVISIBLE
actionMenuLayout.visibility = View.VISIBLE
val mainActivity =
launcherApps.getActivityList(appInfo.applicationInfo.packageName, userHandle)
.firstOrNull()
appActionMenu.setActionListeners(
this@MainActivity,
CoroutineScope(Dispatchers.Main),
binding,
textView,
editView,
actionMenuLayout,
searchView,
appInfo.applicationInfo,
userHandle,
userProfile,
launcherApps,
mainActivity,
position
)
}
fun manualRefresh() {
CoroutineScope(Dispatchers.Default).launch {
try {
val updatedApps = appUtils.getInstalledApps(this@MainActivity)
val changes = detectChanges(installedApps, updatedApps)
installedApps = updatedApps
withContext(Dispatchers.Main) {
applyChanges(changes, installedApps)
}
}
catch (_: UninitializedPropertyAccessException) {
}
}
}
private 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 updates
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))
}
}
}
// Detect insertions
newList.forEachIndexed { index, newItem ->
if (!oldSet.contains(Pair(newItem.first.applicationInfo.packageName, newItem.second.second))) {
changes.add(Change(ChangeType.INSERT, index))
}
}
// Detect removals
oldList.forEachIndexed { index, oldItem ->
if (!newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
removalChanges.add(Change(ChangeType.REMOVE, index))
}
}
changes.addAll(removalChanges.reversed())
return changes
}
private 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])
}
}
}
}
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)
}
fun updateItem(position: Int, app: Pair<LauncherActivityInfo, Pair<UserHandle, Int>>) {
adapter.updateApp(position, app)
adapter.notifyItemChanged(position)
}
fun moveItem(position: Int, newPosition: Int) {
Log.d("Movestatus","MOVED")
adapter.moveApp(position, newPosition)
adapter.notifyItemMoved(position, newPosition)
}
} }
data class Change(val type: ChangeType, val position: Int, val newPosition: Int = 0)
enum class ChangeType {
INSERT, REMOVE, UPDATE
}

View file

@ -1,37 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout 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" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/home_view" android:id="@+id/main_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="bottom" android:layout_gravity="fill_vertical"
android:fillViewport="true"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:gravity="bottom"
android:orientation="vertical" android:orientation="vertical"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextClock
android:id="@+id/text_clock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="20dp"
android:fontFamily="@null"
android:textAlignment="center"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="70sp" />
<LinearLayout <LinearLayout
android:id="@+id/shortcuts" android:id="@+id/app_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:gravity="center_vertical" android:gravity="bottom"
android:orientation="vertical"> android:orientation="vertical"
android:visibility="gone">
<Space
android:layout_width="match_parent"
android:layout_height="60dp" />
<TextView <TextView
android:id="@+id/app1" android:id="@+id/menutitle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="false" android:clickable="false"
@ -40,129 +32,215 @@
android:paddingTop="20dp" android:paddingTop="20dp"
android:paddingRight="40dp" android:paddingRight="40dp"
android:paddingBottom="20dp" android:paddingBottom="20dp"
android:text="App" android:text="Select an app"
android:textAppearance="@android:style/TextAppearance.DeviceDefault" android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3" android:textColor="#C1F3F3F3"
android:textSize="28sp" android:textSize="36sp"
android:visibility="visible" /> android:visibility="gone" />
<TextView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/app2" android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:clickable="false" android:layout_weight="1"
android:gravity="start" android:clipToPadding="false"
android:paddingLeft="40dp" android:fadingEdgeLength="20dp"
android:paddingTop="20dp" android:padding="0dp"
android:paddingRight="40dp" android:requiresFadingEdge="vertical"
android:paddingBottom="20dp" android:scrollbars="none"
android:text="App" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:textAppearance="@android:style/TextAppearance.DeviceDefault" app:stackFromEnd="true">
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView </androidx.recyclerview.widget.RecyclerView>
android:id="@+id/app3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView <com.google.android.material.textfield.TextInputEditText
android:id="@+id/app4" android:id="@+id/searchView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:clickable="false" android:layout_gravity="bottom"
android:gravity="start" android:layout_marginHorizontal="40dp"
android:paddingLeft="40dp" android:layout_marginTop="20dp"
android:paddingTop="20dp" android:layout_marginBottom="40dp"
android:paddingRight="40dp" android:layout_weight="0.1"
android:paddingBottom="20dp" android:background="@android:color/transparent"
android:text="App" android:cursorVisible="true"
android:drawableLeft="@android:drawable/ic_menu_search"
android:drawablePadding="8dp"
android:editTextColor="#f3f3f3"
android:hint="Search..."
android:singleLine="true"
android:textAppearance="@android:style/TextAppearance.DeviceDefault" android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3" android:textSize="25sp" />
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
</LinearLayout> </LinearLayout>
<Space <LinearLayout
android:id="@+id/home_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="1" /> android:layout_gravity="fill_vertical"
android:fitsSystemWindows="true"
android:gravity="fill_vertical"
android:orientation="vertical">
</LinearLayout> <TextClock
android:id="@+id/text_clock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="20dp"
android:fontFamily="@null"
android:textAlignment="center"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="70sp" />
<LinearLayout
android:id="@+id/shortcuts"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="top"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="@+id/app1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoSizeTextType="uniform"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible" />
<TextView
android:id="@+id/app5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="gone" />
<TextView
android:id="@+id/app6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="gone" />
<TextView
android:id="@+id/app7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="gone" />
<TextView
android:id="@+id/app8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="App"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="gone" />
</LinearLayout>
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.15" />
</LinearLayout>
</FrameLayout>