mirror of
https://github.com/He4eT/yamf_launcher.git
synced 2026-05-04 17:37:25 +00:00
Refactoring everything into a recyclerview. Missing: UI Design, Renaming functionality
This commit is contained in:
parent
3adaa4a8b0
commit
f21f13ba6c
8 changed files with 433 additions and 60 deletions
|
|
@ -47,6 +47,7 @@ dependencies {
|
||||||
implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
|
implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
|
||||||
implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
|
implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
|
||||||
implementation("com.google.code.gson:gson:2.10")
|
implementation("com.google.code.gson:gson:2.10")
|
||||||
|
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||||
testImplementation("junit:junit:4.13.2")
|
testImplementation("junit:junit:4.13.2")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||||
|
|
|
||||||
118
app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt
Normal file
118
app/src/main/java/eu/ottop/yamlauncher/AppActionMenu.kt
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
package eu.ottop.yamlauncher
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.LauncherActivityInfo
|
||||||
|
import android.content.pm.LauncherApps
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.os.UserHandle
|
||||||
|
import android.view.View
|
||||||
|
import android.view.inputmethod.EditorInfo
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.SearchView
|
||||||
|
import android.widget.TextView
|
||||||
|
import eu.ottop.yamlauncher.databinding.ActivityAppMenuBinding
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class AppActionMenu {
|
||||||
|
|
||||||
|
private val sharedPreferenceManager = SharedPreferenceManager()
|
||||||
|
|
||||||
|
fun setActionListeners(
|
||||||
|
activity: AppMenuActivity,
|
||||||
|
uiScope: CoroutineScope,
|
||||||
|
binding: ActivityAppMenuBinding,
|
||||||
|
textView: TextView,
|
||||||
|
editLayout: LinearLayout,
|
||||||
|
actionMenu: View,
|
||||||
|
searchView: SearchView,
|
||||||
|
appInfo: ApplicationInfo,
|
||||||
|
userHandle: UserHandle,
|
||||||
|
workProfile: Int,
|
||||||
|
launcherApps: LauncherApps,
|
||||||
|
mainActivity: LauncherActivityInfo?
|
||||||
|
){
|
||||||
|
|
||||||
|
actionMenu.findViewById<TextView>(R.id.info).setOnClickListener {
|
||||||
|
if (mainActivity != null) {
|
||||||
|
launcherApps.startAppDetailsActivity(
|
||||||
|
mainActivity.componentName,
|
||||||
|
userHandle,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
actionMenu.visibility = View.GONE
|
||||||
|
textView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
actionMenu.findViewById<TextView>(R.id.uninstall).setOnClickListener {
|
||||||
|
val intent = Intent(Intent.ACTION_DELETE)
|
||||||
|
intent.data = Uri.parse("package:${appInfo.packageName}")
|
||||||
|
intent.putExtra(Intent.EXTRA_USER, userHandle)
|
||||||
|
activity.startActivity(intent)
|
||||||
|
|
||||||
|
actionMenu.visibility = View.GONE
|
||||||
|
textView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
actionMenu.findViewById<TextView>(R.id.rename).setOnClickListener {
|
||||||
|
textView.visibility = View.GONE
|
||||||
|
editLayout.visibility = View.VISIBLE
|
||||||
|
actionMenu.visibility = View.GONE
|
||||||
|
val editText = editLayout.findViewById<EditText>(R.id.app_name)
|
||||||
|
searchView.visibility = View.GONE
|
||||||
|
editText.requestFocus()
|
||||||
|
|
||||||
|
val handler = Handler(Looper.getMainLooper())
|
||||||
|
handler.postDelayed({
|
||||||
|
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
|
||||||
|
//binding.appList.scrollToDescendant(textView)
|
||||||
|
}, 100)
|
||||||
|
|
||||||
|
binding.root.addOnLayoutChangeListener {
|
||||||
|
_, _, top, _, bottom, _, oldTop, _, oldBottom ->
|
||||||
|
if (bottom - top > oldBottom - oldTop) {
|
||||||
|
editLayout.clearFocus()
|
||||||
|
|
||||||
|
editLayout.visibility = View.GONE
|
||||||
|
textView.visibility = View.VISIBLE
|
||||||
|
searchView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editText.setOnEditorActionListener { _, actionId, _ ->
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
|
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
imm.hideSoftInputFromWindow(editText.windowToken, 0)
|
||||||
|
sharedPreferenceManager.setAppName(activity, appInfo.packageName, workProfile, editText.text.toString())
|
||||||
|
uiScope.launch {
|
||||||
|
//activity.refreshAppMenu()
|
||||||
|
}
|
||||||
|
|
||||||
|
return@setOnEditorActionListener true
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actionMenu.findViewById<TextView>(R.id.hide).setOnClickListener {
|
||||||
|
sharedPreferenceManager.setAppHidden(activity, appInfo.packageName, workProfile, true)
|
||||||
|
actionMenu.visibility = View.GONE
|
||||||
|
textView.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
actionMenu.findViewById<TextView>(R.id.close).setOnClickListener {
|
||||||
|
actionMenu.visibility = View.GONE
|
||||||
|
textView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,41 +1,208 @@
|
||||||
package eu.ottop.yamlauncher
|
package eu.ottop.yamlauncher
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.ApplicationInfo
|
|
||||||
import android.content.pm.LauncherActivityInfo
|
import android.content.pm.LauncherActivityInfo
|
||||||
import android.content.pm.LauncherApps
|
import android.content.pm.LauncherApps
|
||||||
import android.content.res.ColorStateList
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import android.webkit.RenderProcessGoneDetail
|
|
||||||
import android.widget.EditText
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.PopupWindow
|
|
||||||
import android.widget.SearchView
|
import android.widget.SearchView
|
||||||
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.graphics.drawable.toDrawable
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import eu.ottop.yamlauncher.databinding.ActivityAppMenuBinding
|
import eu.ottop.yamlauncher.databinding.ActivityAppMenuBinding
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
|
||||||
class AppMenuActivity : AppCompatActivity() {
|
class AppMenuActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, AppMenuAdapter.OnItemLongClickListener {
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityAppMenuBinding
|
||||||
|
private lateinit var recyclerView: RecyclerView
|
||||||
|
private lateinit var searchView: SearchView
|
||||||
|
private lateinit var adapter: AppMenuAdapter
|
||||||
|
private lateinit var shownApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
|
||||||
|
private lateinit var job: Job
|
||||||
|
private var appActionMenu = AppActionMenu()
|
||||||
|
private lateinit var launcherApps: LauncherApps
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = ActivityAppMenuBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
setSupportActionBar(null)
|
||||||
|
launcherApps = getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||||
|
searchView = findViewById(R.id.searchView)
|
||||||
|
|
||||||
|
recyclerView = findViewById(R.id.recycler_view)
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
|
shownApps = getInstalledApps()
|
||||||
|
adapter = AppMenuAdapter(shownApps, this, this)
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
// Handle the case when launch intent is null (e.g., app cannot be launched)
|
||||||
|
Toast.makeText(this, "Cannot launch app", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemLongClick(
|
||||||
|
appInfo: LauncherActivityInfo,
|
||||||
|
userHandle: UserHandle,
|
||||||
|
userProfile: Int,
|
||||||
|
textView: TextView,
|
||||||
|
actionMenuLayout: LinearLayout,
|
||||||
|
editView: LinearLayout
|
||||||
|
) {
|
||||||
|
// Handle the long click action here, for example, show additional options or information about the app
|
||||||
|
textView.visibility = View.GONE
|
||||||
|
actionMenuLayout.visibility = View.VISIBLE
|
||||||
|
val mainActivity = launcherApps.getActivityList(appInfo.applicationInfo.packageName, userHandle).firstOrNull()
|
||||||
|
appActionMenu.setActionListeners(this@AppMenuActivity, CoroutineScope(Dispatchers.Main), binding, textView, editView, actionMenuLayout, searchView, appInfo.applicationInfo, userHandle, userProfile, launcherApps, mainActivity)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getInstalledApps(): List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>> {
|
||||||
|
val allApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
|
||||||
|
val launcherApps = getSystemService(LAUNCHER_APPS_SERVICE) as LauncherApps
|
||||||
|
for (i in launcherApps.profiles.indices) {
|
||||||
|
launcherApps.getActivityList(null, launcherApps.profiles[i]).forEach { app ->
|
||||||
|
allApps.add(Pair(app, Pair(launcherApps.profiles[i], i)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allApps.sortedBy {
|
||||||
|
it.first.applicationInfo.loadLabel(packageManager).toString().lowercase()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
job.cancel()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
startTask()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startTask() {
|
||||||
|
job = CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
while (true) {
|
||||||
|
if (!listsEqual(shownApps, getInstalledApps())) {
|
||||||
|
shownApps = getInstalledApps()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter.updateApps(shownApps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay(5000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun listsEqual(
|
||||||
|
list1: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
|
||||||
|
list2: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>
|
||||||
|
): Boolean {
|
||||||
|
if (list1.size != list2.size) return false
|
||||||
|
|
||||||
|
for (i in list1.indices) {
|
||||||
|
if (list1[i].first.componentName != list2[i].first.componentName || list1[i].second.first != list2[i].second.first) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppMenuAdapter(private var apps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>, private val itemClickListener: OnItemClickListener, private val itemLongClickListener: OnItemLongClickListener) :
|
||||||
|
RecyclerView.Adapter<AppMenuAdapter.AppViewHolder>() {
|
||||||
|
|
||||||
|
interface OnItemClickListener {
|
||||||
|
fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OnItemLongClickListener {
|
||||||
|
fun onItemLongClick(
|
||||||
|
appInfo: LauncherActivityInfo,
|
||||||
|
userHandle: UserHandle,
|
||||||
|
userProfile: Int,
|
||||||
|
textView: TextView,
|
||||||
|
actionMenuLayout: LinearLayout,
|
||||||
|
editView: LinearLayout
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
val textView: TextView = itemView.findViewById(R.id.app_name)
|
||||||
|
|
||||||
|
init {
|
||||||
|
val actionMenuLayout = LayoutInflater.from(itemView.context)
|
||||||
|
.inflate(R.layout.app_action_menu, itemView.findViewById(R.id.list_item), false) as LinearLayout
|
||||||
|
val editView = LayoutInflater.from(itemView.context)
|
||||||
|
.inflate(R.layout.rename_view, itemView.findViewById(R.id.list_item), false) as LinearLayout
|
||||||
|
val parentLayout: ViewGroup = itemView.findViewById(R.id.list_item)
|
||||||
|
parentLayout.addView(actionMenuLayout)
|
||||||
|
parentLayout.addView(editView)
|
||||||
|
actionMenuLayout.visibility = View.GONE
|
||||||
|
editView.visibility = View.GONE
|
||||||
|
itemView.setOnClickListener {
|
||||||
|
val position = bindingAdapterPosition
|
||||||
|
if (position != RecyclerView.NO_POSITION) {
|
||||||
|
val app = apps[position].first
|
||||||
|
itemClickListener.onItemClick(app, apps[position].second.first)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itemView.setOnLongClickListener {
|
||||||
|
val position = bindingAdapterPosition
|
||||||
|
if (position != RecyclerView.NO_POSITION) {
|
||||||
|
val app = apps[position].first
|
||||||
|
itemLongClickListener.onItemLongClick(app, apps[position].second.first, apps[position].second.second, textView, actionMenuLayout, editView)
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder {
|
||||||
|
val view = LayoutInflater.from(parent.context)
|
||||||
|
.inflate(R.layout.app_item_layout, parent, false)
|
||||||
|
return AppViewHolder(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
|
||||||
|
val app = apps[position]
|
||||||
|
val appInfo = app.first.activityInfo.applicationInfo
|
||||||
|
holder.textView.text = appInfo.loadLabel(holder.itemView.context.packageManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return apps.size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateApps(newApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
|
||||||
|
apps = newApps
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
private lateinit var binding: ActivityAppMenuBinding
|
private lateinit var binding: ActivityAppMenuBinding
|
||||||
private lateinit var searchView: SearchView
|
private lateinit var searchView: SearchView
|
||||||
private lateinit var container: LinearLayout
|
private lateinit var container: LinearLayout
|
||||||
|
|
@ -415,4 +582,4 @@ class AppMenuActivity : AppCompatActivity() {
|
||||||
val key = "$packageName-$profile"
|
val key = "$packageName-$profile"
|
||||||
return sharedPreferences.getString(key, appName.toString())
|
return sharedPreferences.getString(key, appName.toString())
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
package eu.ottop.yamlauncher
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
class SharedPreferenceManager {
|
||||||
|
|
||||||
|
fun setAppHidden(cont: Context, packageName: String, profile: Int, hidden: Boolean) {
|
||||||
|
val editor = cont.getSharedPreferences("hidden_apps", AppCompatActivity.MODE_PRIVATE).edit()
|
||||||
|
val key = "$packageName-$profile"
|
||||||
|
editor.putBoolean(key, hidden)
|
||||||
|
editor.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAppHidden(cont: Context, packageName: String, profile: Int): Boolean {
|
||||||
|
val sharedPref = cont.getSharedPreferences("hidden_apps", AppCompatActivity.MODE_PRIVATE)
|
||||||
|
val key = "$packageName-$profile"
|
||||||
|
return sharedPref.getBoolean(key, false) // Default to false (visible)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setAppVisible(cont: Context, packageName: String, profile: Int) {
|
||||||
|
val editor = cont.getSharedPreferences("hidden_apps", AppCompatActivity.MODE_PRIVATE).edit()
|
||||||
|
val key = "$packageName-$profile"
|
||||||
|
editor.remove(key)
|
||||||
|
editor.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setAppName(cont: Context, packageName: String, profile: Int, newName: String) {
|
||||||
|
val editor = cont.getSharedPreferences("renamed_apps", AppCompatActivity.MODE_PRIVATE).edit()
|
||||||
|
val key = "$packageName-$profile"
|
||||||
|
editor.putString(key, newName)
|
||||||
|
editor.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAppName(cont: Context, packageName: String, profile: Int, appName: CharSequence): CharSequence? {
|
||||||
|
val sharedPreferences = cont.getSharedPreferences("renamed_apps", AppCompatActivity.MODE_PRIVATE)
|
||||||
|
val key = "$packageName-$profile"
|
||||||
|
return sharedPreferences.getString(key, appName.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resetAppName(cont: Context, packageName: String, profile: Int) {
|
||||||
|
val editor = cont.getSharedPreferences("renamed_apps", AppCompatActivity.MODE_PRIVATE).edit()
|
||||||
|
val key = "$packageName-$profile"
|
||||||
|
editor.remove(key)
|
||||||
|
editor.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,39 +1,21 @@
|
||||||
<?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/app_menu"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="bottom"
|
android:orientation="vertical">
|
||||||
android:fillViewport="true"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
android:gravity="bottom"
|
|
||||||
android:orientation="vertical"
|
|
||||||
tools:context=".MainActivity">
|
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
<ScrollView
|
android:id="@+id/recycler_view"
|
||||||
android:id="@+id/app_list"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_gravity="bottom"
|
android:layout_weight="1"
|
||||||
android:layout_marginHorizontal="10dp"
|
android:clipToPadding="false"
|
||||||
android:layout_marginTop="25dp"
|
android:padding="0dp"
|
||||||
android:layout_weight="0.9"
|
android:scrollbars="none"
|
||||||
android:fadingEdge="none"
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager">
|
||||||
android:fillViewport="true"
|
|
||||||
android:requiresFadingEdge="vertical"
|
|
||||||
android:scrollbars="none">
|
|
||||||
|
|
||||||
<LinearLayout
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
android:id="@+id/container"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fadingEdge="none"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:padding="16dp"/>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
<SearchView
|
<SearchView
|
||||||
android:id="@+id/searchView"
|
android:id="@+id/searchView"
|
||||||
|
|
@ -51,4 +33,5 @@
|
||||||
android:queryHint="Search..."
|
android:queryHint="Search..."
|
||||||
android:theme="@style/AppSearchView" />
|
android:theme="@style/AppSearchView" />
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -1,51 +1,69 @@
|
||||||
<?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"
|
||||||
|
android:id="@+id/action_menu"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="#6F000000">
|
android:gravity="center">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/info"
|
android:id="@+id/info"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:drawableTop="@android:drawable/ic_menu_info_details"
|
android:background="#6F000000"
|
||||||
android:foreground="@drawable/app_action_foreground"
|
android:foreground="@drawable/app_action_foreground"
|
||||||
android:text="Info"
|
android:text="Info"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="#F3F3F3FF" />
|
android:textColor="#F3F3F3FF"
|
||||||
|
app:drawableTopCompat="@android:drawable/ic_menu_info_details" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/uninstall"
|
android:id="@+id/uninstall"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:drawableTop="@android:drawable/ic_menu_delete"
|
android:background="#6F000000"
|
||||||
android:foreground="@drawable/app_action_foreground"
|
android:foreground="@drawable/app_action_foreground"
|
||||||
android:text="Uninstall"
|
android:text="Uninstall"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="#F3F3F3FF" />
|
android:textColor="#F3F3F3FF"
|
||||||
|
app:drawableTopCompat="@android:drawable/ic_menu_delete" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/rename"
|
android:id="@+id/rename"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:drawableTop="@android:drawable/ic_menu_edit"
|
android:background="#6F000000"
|
||||||
android:foreground="@drawable/app_action_foreground"
|
android:foreground="@drawable/app_action_foreground"
|
||||||
android:text="Rename"
|
android:text="Rename"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="#F3F3F3FF" />
|
android:textColor="#F3F3F3FF"
|
||||||
|
app:drawableTopCompat="@android:drawable/ic_menu_edit" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/hide"
|
android:id="@+id/hide"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:drawableTop="@android:drawable/ic_menu_view"
|
android:background="#6F000000"
|
||||||
android:foreground="@drawable/app_action_foreground"
|
android:foreground="@drawable/app_action_foreground"
|
||||||
android:text="Hide"
|
android:text="Hide"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textColor="#F3F3F3FF" />
|
android:textColor="#F3F3F3FF"
|
||||||
|
app:drawableTopCompat="@android:drawable/ic_menu_view" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/close"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="#6F000000"
|
||||||
|
android:foreground="@drawable/app_action_foreground"
|
||||||
|
android:text="Close"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="#F3F3F3FF"
|
||||||
|
app:drawableTopCompat="@android:drawable/ic_menu_close_clear_cancel" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
18
app/src/main/res/layout/app_item_layout.xml
Normal file
18
app/src/main/res/layout/app_item_layout.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/list_item"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="0dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/app_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="#F3F3F3"
|
||||||
|
android:textSize="28sp"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
20
app/src/main/res/layout/rename_view.xml
Normal file
20
app/src/main/res/layout/rename_view.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/rename_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/app_name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:hint="hint" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button2"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.3"
|
||||||
|
android:text="Reset" />
|
||||||
|
</LinearLayout>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue