11package com.mrepol742.webviumlauncher
22
3+ import android.content.Intent
4+ import android.graphics.Color
5+ import android.graphics.RenderEffect
6+ import android.graphics.Shader
7+ import android.os.Build
38import android.os.Bundle
9+ import android.view.View
10+ import android.widget.SearchView
411import androidx.activity.ComponentActivity
512import androidx.activity.compose.setContent
613import androidx.activity.enableEdgeToEdge
@@ -11,37 +18,112 @@ import androidx.compose.material3.Text
1118import androidx.compose.runtime.Composable
1219import androidx.compose.ui.Modifier
1320import androidx.compose.ui.tooling.preview.Preview
21+ import androidx.core.view.ViewCompat
22+ import androidx.core.view.WindowCompat
23+ import androidx.core.view.WindowInsetsCompat
24+ import androidx.recyclerview.widget.GridLayoutManager
25+ import androidx.recyclerview.widget.RecyclerView
1426import com.mrepol742.webviumlauncher.ui.theme.WebviumLauncherTheme
1527
1628class MainActivity : ComponentActivity () {
29+
30+ private lateinit var recyclerView: RecyclerView
31+ private lateinit var searchView: SearchView
32+ private lateinit var adapter: AppAdapter
33+
34+ private val allApps = mutableListOf<AppInfo >()
35+ private val filteredApps = mutableListOf<AppInfo >()
36+
1737 override fun onCreate (savedInstanceState : Bundle ? ) {
1838 super .onCreate(savedInstanceState)
19- enableEdgeToEdge()
20- setContent {
21- WebviumLauncherTheme {
22- Scaffold (modifier = Modifier .fillMaxSize()) { innerPadding ->
23- Greeting (
24- name = " Android" ,
25- modifier = Modifier .padding(innerPadding)
26- )
27- }
28- }
39+ enableEdgeToEdge();
40+ setContentView(R .layout.activity_main)
41+
42+ val root = findViewById<View >(R .id.root)
43+ val blurLayer = findViewById<View >(R .id.blurLayer)
44+ recyclerView = findViewById(R .id.recyclerView)
45+ searchView = findViewById(R .id.searchView)
46+
47+ recyclerView.layoutManager = GridLayoutManager (this , 4 )
48+ ViewCompat .setOnApplyWindowInsetsListener(root) { view, insets ->
49+ val statusBarInsets = insets.getInsets(WindowInsetsCompat .Type .statusBars())
50+
51+ view.setPadding(
52+ view.paddingLeft,
53+ statusBarInsets.top,
54+ view.paddingRight,
55+ view.paddingBottom
56+ )
57+
58+ insets
59+ }
60+
61+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .S ) {
62+ blurLayer.setRenderEffect(
63+ RenderEffect .createBlurEffect(
64+ 30f , // radius X
65+ 30f , // radius Y
66+ Shader .TileMode .CLAMP
67+ )
68+ )
69+ }
70+
71+ adapter = AppAdapter (filteredApps) { app ->
72+ startActivity(app.launchIntent)
73+ }
74+
75+ recyclerView.adapter = adapter
76+ setupSearch()
77+ loadApps()
78+ }
79+
80+
81+ private fun loadApps () {
82+ val pm = packageManager
83+ val intent = Intent (Intent .ACTION_MAIN , null )
84+ intent.addCategory(Intent .CATEGORY_LAUNCHER )
85+
86+ val resolveInfos = pm.queryIntentActivities(intent, 0 )
87+
88+ allApps.clear()
89+ for (info in resolveInfos) {
90+ val label = info.loadLabel(pm).toString()
91+ val packageName = info.activityInfo.packageName
92+ val icon = info.loadIcon(pm)
93+ val launchIntent = pm.getLaunchIntentForPackage(packageName) ? : continue
94+
95+
96+ allApps.add(AppInfo (label, packageName, icon, launchIntent))
2997 }
98+
99+ allApps.sortBy { it.label.lowercase() }
100+ filteredApps.clear()
101+ filteredApps.addAll(allApps)
102+ adapter.notifyDataSetChanged()
30103 }
31- }
32-
33- @Composable
34- fun Greeting (name : String , modifier : Modifier = Modifier ) {
35- Text (
36- text = " Hello $name !" ,
37- modifier = modifier
38- )
39- }
40-
41- @Preview(showBackground = true )
42- @Composable
43- fun GreetingPreview () {
44- WebviumLauncherTheme {
45- Greeting (" Android" )
104+
105+ private fun setupSearch () {
106+ searchView.setOnQueryTextListener(object : SearchView .OnQueryTextListener {
107+ override fun onQueryTextSubmit (query : String? ): Boolean = false
108+
109+
110+ override fun onQueryTextChange (newText : String? ): Boolean {
111+ val q = newText.orEmpty().lowercase()
112+ filteredApps.clear()
113+
114+
115+ if (q.isEmpty()) {
116+ filteredApps.addAll(allApps)
117+ } else {
118+ filteredApps.addAll(allApps.filter {
119+ it.label.lowercase().contains(q)
120+ })
121+ }
122+
123+
124+ adapter.notifyDataSetChanged()
125+ return true
126+ }
127+ })
46128 }
47129}
0 commit comments