...
This commit is contained in:
parent
85e3ac1414
commit
b8c08da378
@ -70,4 +70,5 @@ dependencies {
|
||||
implementation ("com.google.android.material:material:1.10.0")
|
||||
implementation (kotlin("stdlib", version = kotlinVersion))
|
||||
implementation ("com.github.cachapa:ExpandableLayout:2.9.2")
|
||||
implementation ("com.squareup.picasso:picasso:2.8")
|
||||
}
|
||||
|
||||
@ -19,6 +19,9 @@
|
||||
|
||||
<!-- api 33+ -->
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
|
||||
@ -1,118 +1,112 @@
|
||||
/*
|
||||
* Lunar Launcher
|
||||
* Copyright (C) 2022 Md Rasel Hossain
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package rasel.lunar.launcher.apps
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import rasel.lunar.launcher.apps.AppDrawer.Companion.alphabetList
|
||||
import rasel.lunar.launcher.apps.AppDrawer.Companion.letterPreview
|
||||
import rasel.lunar.launcher.apps.AppDrawer.Companion.listenScroll
|
||||
import rasel.lunar.launcher.apps.AppDrawer.Companion.settingsPrefs
|
||||
import rasel.lunar.launcher.apps.AppsAdapter.Companion.appsSize
|
||||
import rasel.lunar.launcher.helpers.Constants
|
||||
|
||||
|
||||
internal class AlphabetScrollbar : View {
|
||||
|
||||
private var paint: Paint? = null
|
||||
private var selectedIndex = -1
|
||||
private val alphabet get() = alphabetList.distinct()
|
||||
|
||||
constructor(context: Context?) : super(context) {
|
||||
init()
|
||||
}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
init()
|
||||
}
|
||||
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
init()
|
||||
}
|
||||
|
||||
@SuppressLint("ResourceType")
|
||||
private fun init() {
|
||||
paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
color = defaultTextColor
|
||||
textSize = 16f
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
val width = width
|
||||
val height = height
|
||||
val letterHeight: Int = height / alphabet.count()
|
||||
alphabet.indices.forEach { i: Int ->
|
||||
val x = width / 2f - paint!!.measureText(alphabet[i]) / 2f
|
||||
val y = i * letterHeight + letterHeight / 2f
|
||||
when (i) {
|
||||
selectedIndex -> paint!!.textSize = 20f
|
||||
else -> paint!!.textSize = 16f
|
||||
}
|
||||
canvas.drawText(alphabet[i], x, y, paint!!)
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
|
||||
val y = event.y
|
||||
val index = (y / height * alphabet.count()).toInt()
|
||||
if (index != selectedIndex) {
|
||||
selectedIndex = index
|
||||
invalidate()
|
||||
}
|
||||
|
||||
if (!settingsPrefs!!.getBoolean(Constants.KEY_APPS_COUNT, true)) letterPreview?.visibility = VISIBLE
|
||||
try { letterPreview?.text = alphabet[selectedIndex] }
|
||||
catch (exception: Exception) { exception.printStackTrace() }
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
when {
|
||||
selectedIndex < 0 -> listenScroll(alphabet[0])
|
||||
selectedIndex > alphabet.count() - 1 -> listenScroll(alphabet[alphabet.count() - 1])
|
||||
else -> listenScroll(alphabet[selectedIndex])
|
||||
}
|
||||
|
||||
selectedIndex = -1
|
||||
invalidate()
|
||||
if (settingsPrefs!!.getBoolean(Constants.KEY_APPS_COUNT, true)) letterPreview?.text = appsSize.toString()
|
||||
else letterPreview?.visibility = GONE
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private val defaultTextColor: Int get() {
|
||||
val resolvedAttr = TypedValue()
|
||||
context.theme.resolveAttribute(android.R.attr.textColorPrimary, resolvedAttr, true)
|
||||
val colorRes = resolvedAttr.run { if (resourceId != 0) resourceId else data }
|
||||
return ContextCompat.getColor(context, colorRes)
|
||||
}
|
||||
}
|
||||
///*
|
||||
// * Lunar Launcher
|
||||
// * Copyright (C) 2022 Md Rasel Hossain
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have received a copy of the GNU General Public License
|
||||
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// */
|
||||
//
|
||||
//package rasel.lunar.launcher.apps
|
||||
//
|
||||
//import android.annotation.SuppressLint
|
||||
//import android.content.Context
|
||||
//import android.graphics.Canvas
|
||||
//import android.graphics.Paint
|
||||
//import android.util.AttributeSet
|
||||
//import android.util.TypedValue
|
||||
//import android.view.MotionEvent
|
||||
//import android.view.View
|
||||
//import androidx.core.content.ContextCompat
|
||||
//
|
||||
//
|
||||
//internal class AlphabetScrollbar : View {
|
||||
//
|
||||
// private var paint: Paint? = null
|
||||
// private var selectedIndex = -1
|
||||
//// private val alphabet get() = alphabetList.distinct()
|
||||
//
|
||||
// constructor(context: Context?) : super(context) {
|
||||
// init()
|
||||
// }
|
||||
//
|
||||
// constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
|
||||
// init()
|
||||
// }
|
||||
//
|
||||
// constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
// init()
|
||||
// }
|
||||
//
|
||||
// @SuppressLint("ResourceType")
|
||||
// private fun init() {
|
||||
// paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
// color = defaultTextColor
|
||||
// textSize = 16f
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onDraw(canvas: Canvas) {
|
||||
// super.onDraw(canvas)
|
||||
// val width = width
|
||||
// val height = height
|
||||
// val letterHeight: Int = height / alphabet.count()
|
||||
// alphabet.indices.forEach { i: Int ->
|
||||
// val x = width / 2f - paint!!.measureText(alphabet[i]) / 2f
|
||||
// val y = i * letterHeight + letterHeight / 2f
|
||||
// when (i) {
|
||||
// selectedIndex -> paint!!.textSize = 20f
|
||||
// else -> paint!!.textSize = 16f
|
||||
// }
|
||||
// canvas.drawText(alphabet[i], x, y, paint!!)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @SuppressLint("ClickableViewAccessibility")
|
||||
// override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
//// when (event.action) {
|
||||
//// MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
|
||||
//// val y = event.y
|
||||
//// val index = (y / height * alphabet.count()).toInt()
|
||||
//// if (index != selectedIndex) {
|
||||
//// selectedIndex = index
|
||||
//// invalidate()
|
||||
//// }
|
||||
////
|
||||
//// if (!settingsPrefs!!.getBoolean(Constants.KEY_APPS_COUNT, true)) letterPreview?.visibility = VISIBLE
|
||||
//// try { letterPreview?.text = alphabet[selectedIndex] }
|
||||
//// catch (exception: Exception) { exception.printStackTrace() }
|
||||
//// }
|
||||
////
|
||||
//// MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
//// when {
|
||||
//// selectedIndex < 0 -> listenScroll(alphabet[0])
|
||||
//// selectedIndex > alphabet.count() - 1 -> listenScroll(alphabet[alphabet.count() - 1])
|
||||
//// else -> listenScroll(alphabet[selectedIndex])
|
||||
//// }
|
||||
////
|
||||
//// selectedIndex = -1
|
||||
//// invalidate()
|
||||
//// if (settingsPrefs!!.getBoolean(Constants.KEY_APPS_COUNT, true)) letterPreview?.text = appsSize.toString()
|
||||
//// else letterPreview?.visibility = GONE
|
||||
//// }
|
||||
//// }
|
||||
// return true
|
||||
// }
|
||||
//
|
||||
// private val defaultTextColor: Int get() {
|
||||
// val resolvedAttr = TypedValue()
|
||||
// context.theme.resolveAttribute(android.R.attr.textColorPrimary, resolvedAttr, true)
|
||||
// val colorRes = resolvedAttr.run { if (resourceId != 0) resourceId else data }
|
||||
// return ContextCompat.getColor(context, colorRes)
|
||||
// }
|
||||
//}
|
||||
@ -27,6 +27,7 @@ import android.content.pm.ResolveInfo
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings.Global
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@ -41,6 +42,9 @@ import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.textview.MaterialTextView
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import rasel.lunar.launcher.BuildConfig
|
||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
import rasel.lunar.launcher.R
|
||||
@ -75,42 +79,25 @@ internal class AppDrawer : Fragment() {
|
||||
private var appsAdapter: AppsAdapter? = null
|
||||
private var packageInfoList: MutableList<ResolveInfo> = mutableListOf()
|
||||
private var packageList = mutableListOf<Packages>()
|
||||
private var packageListClone = mutableListOf<Packages>()
|
||||
private val numberPattern = Pattern.compile("[0-9]")
|
||||
private val alphabetPattern = Pattern.compile("[A-Z]")
|
||||
|
||||
// private val numberPattern = Pattern.compile("[0-9]")
|
||||
// private val alphabetPattern = Pattern.compile("[A-Z]")
|
||||
@JvmStatic var settingsPrefs: SharedPreferences? = null
|
||||
@JvmStatic var appNamesPrefs: SharedPreferences? = null
|
||||
@JvmStatic var alphabetList = mutableListOf<String>()
|
||||
// @JvmStatic var alphabetList = mutableListOf<String>()
|
||||
@JvmStatic var letterPreview: MaterialTextView? = null
|
||||
|
||||
private fun appName(resolver: ResolveInfo): String {
|
||||
return appNamesPrefs?.getString(resolver.activityInfo.packageName, resolver.loadLabel(packageManager).toString())!!
|
||||
if(appNamesPrefs?.contains(resolver.activityInfo.packageName) != null && appNamesPrefs?.getString(resolver.activityInfo.packageName,"")?.length ?: 0 > 0) {
|
||||
return appNamesPrefs?.getString(resolver.activityInfo.packageName,"") ?: ""
|
||||
} else {
|
||||
return resolver.loadLabel(packageManager).toString().apply {
|
||||
appNamesPrefs?.edit()?.putString(resolver.activityInfo.packageName, this)?.apply()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun listenScroll(letter: String) {
|
||||
// packageListClone.clear()
|
||||
// for (resolver in packageInfoList) {
|
||||
// when {
|
||||
// letter == "#" -> {
|
||||
// if (numberPattern.matcher(appName(resolver).first().uppercase()).matches()) {
|
||||
// packageListClone.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
||||
// }
|
||||
// }
|
||||
// alphabetPattern.matcher(letter).matches() -> {
|
||||
// if (appName(resolver).first().uppercase() == letter) {
|
||||
// packageListClone.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
||||
// }
|
||||
// }
|
||||
// letter == "⠶" -> {
|
||||
// if (!numberPattern.matcher(appName(resolver).first().uppercase()).matches() &&
|
||||
// !alphabetPattern.matcher(appName(resolver).first().uppercase()).matches()) {
|
||||
// packageListClone.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// appsAdapter?.updateData(packageListClone.sortedBy { it.appName.lowercase() })
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
@ -126,9 +113,7 @@ internal class AppDrawer : Fragment() {
|
||||
binding.appsCount.visibility = if (settingsPrefs!!.getBoolean(KEY_APPS_COUNT, true)) VISIBLE else GONE
|
||||
|
||||
setLayout()
|
||||
fetchApps()
|
||||
getAlphabetItems()
|
||||
setKeyboardPadding()
|
||||
|
||||
|
||||
return binding.root
|
||||
}
|
||||
@ -140,7 +125,7 @@ internal class AppDrawer : Fragment() {
|
||||
binding.reset.setOnClickListener { onResume() }
|
||||
|
||||
binding.moveDown.setOnClickListener {
|
||||
binding.appsList.smoothScrollToPosition(packageListClone.size - 1)
|
||||
binding.appsList.smoothScrollToPosition(packageList.size - 1)
|
||||
}
|
||||
|
||||
binding.moveUp.setOnClickListener {
|
||||
@ -163,7 +148,7 @@ internal class AppDrawer : Fragment() {
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
fetchApps()
|
||||
getAlphabetItems()
|
||||
setKeyboardPadding()
|
||||
|
||||
binding.appsCount.visibility = if (settingsPrefs!!.getBoolean(KEY_APPS_COUNT, true)) VISIBLE else GONE
|
||||
|
||||
@ -186,7 +171,7 @@ internal class AppDrawer : Fragment() {
|
||||
binding.appsList.layoutManager = LinearLayoutManager(requireContext())
|
||||
appsAdapter!!.updateGravity(settingsPrefs!!.getInt(KEY_DRAW_ALIGN, Gravity.CENTER))
|
||||
}
|
||||
2 -> binding.appsList.layoutManager = GridLayoutManager(requireContext(), settingsPrefs!!.getInt(KEY_GRID_COLUMNS, DEFAULT_GRID_COLUMNS))
|
||||
2 -> binding.appsList.layoutManager = GridLayoutManager(requireContext(), Math.min(settingsPrefs!!.getInt(KEY_GRID_COLUMNS, DEFAULT_GRID_COLUMNS), 4))
|
||||
}
|
||||
|
||||
/* initialize apps list adapter */
|
||||
@ -195,30 +180,39 @@ internal class AppDrawer : Fragment() {
|
||||
|
||||
/* update app list with app and package name */
|
||||
fun fetchApps() {
|
||||
packageInfoList = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
packageManager?.queryIntentActivities(
|
||||
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER),
|
||||
PackageManager.ResolveInfoFlags.of(0)
|
||||
)
|
||||
} else {
|
||||
(packageManager?.queryIntentActivities(
|
||||
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER), 0))
|
||||
})?.apply {
|
||||
removeIf { it.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID) }
|
||||
sortWith(ResolveInfo.DisplayNameComparator(packageManager))
|
||||
}!!
|
||||
GlobalScope.launch {
|
||||
packageInfoList = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
packageManager?.queryIntentActivities(
|
||||
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER),
|
||||
PackageManager.ResolveInfoFlags.of(0)
|
||||
)
|
||||
} else {
|
||||
(packageManager?.queryIntentActivities(
|
||||
Intent(Intent.ACTION_MAIN, null).addCategory(Intent.CATEGORY_LAUNCHER), 0
|
||||
))
|
||||
})?.apply {
|
||||
removeIf { it.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID) }
|
||||
sortedBy {
|
||||
appName(it)
|
||||
}
|
||||
}!!
|
||||
|
||||
/* add package and app names to the list */
|
||||
packageList.clear()
|
||||
packageListClone.clear()
|
||||
for (resolver in packageInfoList) {
|
||||
packageList.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
||||
packageListClone.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
||||
}
|
||||
/* add package and app names to the list */
|
||||
packageList.clear()
|
||||
var edit = appNamesPrefs?.edit()
|
||||
for (resolver in packageInfoList) {
|
||||
packageList.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
||||
}
|
||||
|
||||
when {
|
||||
packageListClone.size < 1 -> return
|
||||
else -> appsAdapter?.updateData(packageListClone.sortedBy { it.appName.lowercase() })
|
||||
// when {
|
||||
// packageList.size < 1 -> return
|
||||
// else -> {
|
||||
if (packageList.size > 0) {
|
||||
MainScope().launch {
|
||||
appsAdapter?.updateData(packageList)
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,43 +241,63 @@ internal class AppDrawer : Fragment() {
|
||||
// }
|
||||
}
|
||||
|
||||
var lastSearchStringLength = 0
|
||||
var lastSearchString : String = ""
|
||||
private fun filterAppsList(searchString: String) {
|
||||
/* check each app name and add if it matches the search string */
|
||||
packageListClone.clear()
|
||||
for (resolver in packageInfoList) {
|
||||
appName(resolver).let {
|
||||
BLog.LOGE("searchString >>> ${searchString} , normalize(it) ${normalize(it)} ${normalize(it).contains(searchString)}")
|
||||
if (normalize(it).contains(searchString)) {
|
||||
packageListClone.add(Packages(resolver.activityInfo.packageName, it))
|
||||
if (lastSearchStringLength > 0 && (lastSearchStringLength != searchString.length || lastSearchString.equals(searchString) == false)) {
|
||||
BLog.LOGE("START FILTER")
|
||||
packageList.clear()
|
||||
for (resolver in packageInfoList) {
|
||||
appName(resolver).let {
|
||||
// BLog.LOGE("searchString >>> ${searchString} , normalize(it) ${normalize(it)} ${normalize(it).contains(normalize(searchString), false)}")
|
||||
if (normalize(it).contains(normalize(searchString), false)) {
|
||||
packageList.add(Packages(resolver.activityInfo.packageName, it))
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchString.length > 2 && packageListClone.size == 1 && settingsPrefs!!.getBoolean(KEY_QUICK_LAUNCH, true)) {
|
||||
var dialog = AlertDialog.Builder(requireContext())
|
||||
dialog.setTitle("앱 실행 확인")
|
||||
dialog.setMessage("${searchString} 검색 결과 '${packageListClone[0].appName}' 준비됨")
|
||||
dialog.setCancelable(false)
|
||||
dialog.setOnCancelListener {
|
||||
binding.searchInput.setText("")
|
||||
it.dismiss()
|
||||
BLog.LOGE("MIDDLE FILTER")
|
||||
if (searchString.length > 2 && packageList.size == 1 && settingsPrefs!!.getBoolean(
|
||||
KEY_QUICK_LAUNCH,
|
||||
true
|
||||
)
|
||||
) {
|
||||
var dialog = AlertDialog.Builder(requireContext())
|
||||
dialog.setTitle("앱 실행 확인")
|
||||
dialog.setMessage("${searchString} 검색 결과 '${packageList[0].appName}' 준비됨")
|
||||
dialog.setCancelable(false)
|
||||
dialog.setNegativeButton("취소") { s,d->
|
||||
binding.searchInput.setText("")
|
||||
s.dismiss()
|
||||
}
|
||||
dialog.setPositiveButton("실행") { s, d ->
|
||||
startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].packageName))
|
||||
s.dismiss()
|
||||
binding.searchInput.setText("")
|
||||
}
|
||||
dialog.show()
|
||||
} else {
|
||||
appsAdapter?.updateData(packageList)
|
||||
}
|
||||
dialog.setPositiveButton("실행") { s,d ->
|
||||
startActivity(packageManager?.getLaunchIntentForPackage(packageListClone[0].packageName))
|
||||
s.dismiss()
|
||||
binding.searchInput.setText("")
|
||||
BLog.LOGE("END FILTER")
|
||||
} else if(lastSearchStringLength == 0){
|
||||
packageList.clear()
|
||||
for (resolver in packageInfoList) {
|
||||
packageList.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
||||
}
|
||||
dialog.show()
|
||||
appsAdapter?.updateData(packageList)
|
||||
}
|
||||
else appsAdapter?.updateData(packageListClone.sortedBy { it.appName.lowercase() })
|
||||
|
||||
lastSearchString = searchString
|
||||
lastSearchStringLength = searchString.length
|
||||
}
|
||||
|
||||
private fun normalize(str: String): String {
|
||||
val normalizedString =
|
||||
Normalizer.normalize(str.replace("\\W".toRegex(), ""), Normalizer.Form.NFD)
|
||||
Normalizer.normalize(str.replace("\\W".toRegex(), ""), Normalizer.Form.NFC)
|
||||
val pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+")
|
||||
return pattern.matcher(normalizedString).replaceAll("").lowercase()
|
||||
return pattern.matcher(normalizedString).replaceAll("").toLowerCase()
|
||||
}
|
||||
|
||||
private fun openSearch() {
|
||||
|
||||
@ -30,6 +30,8 @@ import androidx.fragment.app.FragmentManager
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.textview.MaterialTextView
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.async
|
||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||
import rasel.lunar.launcher.R
|
||||
import rasel.lunar.launcher.apps.IconPackManager.Companion.getDrawableIconForPackage
|
||||
@ -75,7 +77,13 @@ internal class AppsAdapter(
|
||||
}
|
||||
1 -> {
|
||||
appIcon.visibility = View.GONE
|
||||
appIconTwo.setImageDrawable(getDrawableIconForPackage(item.packageName, packageManager.getApplicationIcon(item.packageName)))
|
||||
appIconTwo.visibility = View.VISIBLE
|
||||
|
||||
MainScope().async {
|
||||
getDrawableIconForPackage(item.packageName, packageManager.getApplicationIcon(item.packageName)) {
|
||||
appIconTwo.post { appIconTwo.setImageDrawable(it) }
|
||||
} }
|
||||
|
||||
childTextview.apply {
|
||||
gravity = appGravity or Gravity.CENTER_VERTICAL
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_PX, lActivity!!.resources.getDimension(R.dimen.twenty))
|
||||
@ -85,7 +93,15 @@ internal class AppsAdapter(
|
||||
}
|
||||
2 -> {
|
||||
appIconTwo.visibility = View.GONE
|
||||
appIcon.setImageDrawable(getDrawableIconForPackage(item.packageName, packageManager.getApplicationIcon(item.packageName)))
|
||||
appIcon.visibility = View.VISIBLE
|
||||
MainScope().async {
|
||||
getDrawableIconForPackage(
|
||||
item.packageName,
|
||||
packageManager.getApplicationIcon(item.packageName)
|
||||
) {
|
||||
appIcon.post { appIcon.setImageDrawable(it) }
|
||||
}
|
||||
}
|
||||
childTextview.apply {
|
||||
gravity = Gravity.CENTER
|
||||
setTextSize(TypedValue.COMPLEX_UNIT_PX, lActivity!!.resources.getDimension(R.dimen.twelve))
|
||||
@ -125,7 +141,6 @@ internal class AppsAdapter(
|
||||
appsCount.text = it.toString()
|
||||
appsSize = it
|
||||
}
|
||||
this.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
/* update text gravity (alignment) */
|
||||
@ -138,6 +153,10 @@ internal class AppsAdapter(
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
fun hideItem(idx: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal data class Packages (
|
||||
|
||||
@ -25,7 +25,13 @@ import android.graphics.Bitmap
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.Log
|
||||
import androidx.collection.LruCache
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.squareup.picasso.Picasso
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
import org.xmlpull.v1.XmlPullParserException
|
||||
import org.xmlpull.v1.XmlPullParserFactory
|
||||
@ -47,12 +53,14 @@ internal class IconPackManager {
|
||||
private val packageName = settingsPrefs.getString(KEY_ICON_PACK, DEFAULT_ICON_PACK)
|
||||
private var loaded = false
|
||||
private val packagesDrawables = HashMap<String?, String?>()
|
||||
private val packagesConponentNames = HashMap<String?, String?>()
|
||||
private val backImages: MutableList<Bitmap> = ArrayList()
|
||||
private var maskImage: Bitmap? = null
|
||||
private var frontImage: Bitmap? = null
|
||||
private var factor = 1.0f
|
||||
private var totalIcons = 0
|
||||
private var iconPackRes: Resources? = null
|
||||
private var appPackageIconDrawables : HashMap<String, Drawable> = hashMapOf()
|
||||
|
||||
private fun load() {
|
||||
/* load appfilter.xml from the icon pack package */
|
||||
@ -62,11 +70,14 @@ internal class IconPackManager {
|
||||
val appFilterId = iconPackRes!!.getIdentifier("appfilter", "xml", packageName)
|
||||
if (appFilterId > 0) {
|
||||
xpp = iconPackRes!!.getXml(appFilterId)
|
||||
BLog.LOGE("packageName >>> ${packageName}")
|
||||
} else {
|
||||
/* no resource found, try to open it from assets folder */
|
||||
try {
|
||||
xpp = XmlPullParserFactory.newInstance().apply { isNamespaceAware = true }
|
||||
.newPullParser().apply { setInput(iconPackRes!!.assets.open("appfilter.xml"), "utf-8") }
|
||||
.newPullParser().apply {
|
||||
BLog.LOGE("packageName >>> ${packageName}")
|
||||
setInput(iconPackRes!!.assets.open("appfilter.xml"), "utf-8")
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
BLog.w("", "Couldn't find the appfilter.xml file")
|
||||
@ -78,36 +89,24 @@ internal class IconPackManager {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
when (xpp.name) {
|
||||
"iconback" -> {
|
||||
for (i in 0 until xpp.attributeCount) {
|
||||
if (xpp.getAttributeName(i).startsWith("img")) {
|
||||
loadBitmap(xpp.getAttributeValue(i))?.let { backImages.add(it) }
|
||||
}
|
||||
}
|
||||
for (i in 0 until xpp.attributeCount) { if (xpp.getAttributeName(i).startsWith("img")) { loadBitmap(xpp.getAttributeValue(i))?.let { backImages.add(it) }}}
|
||||
}
|
||||
"iconmask" -> {
|
||||
if (xpp.attributeCount > 0 && xpp.getAttributeName(0) == "img1") {
|
||||
maskImage = loadBitmap(xpp.getAttributeValue(0))
|
||||
}
|
||||
if (xpp.attributeCount > 0 && xpp.getAttributeName(0) == "img1") { maskImage = loadBitmap(xpp.getAttributeValue(0)) }
|
||||
}
|
||||
"iconupon" -> {
|
||||
if (xpp.attributeCount > 0 && xpp.getAttributeName(0) == "img1") {
|
||||
frontImage = loadBitmap(xpp.getAttributeValue(0))
|
||||
}
|
||||
if (xpp.attributeCount > 0 && xpp.getAttributeName(0) == "img1") { frontImage = loadBitmap(xpp.getAttributeValue(0)) }
|
||||
}
|
||||
"scale" -> {
|
||||
if (xpp.attributeCount > 0 && xpp.getAttributeName(0) == "factor") {
|
||||
factor = java.lang.Float.valueOf(xpp.getAttributeValue(0))
|
||||
}
|
||||
if (xpp.attributeCount > 0 && xpp.getAttributeName(0) == "factor") { factor = java.lang.Float.valueOf(xpp.getAttributeValue(0)) }
|
||||
}
|
||||
"item" -> {
|
||||
var componentName: String? = null
|
||||
var drawableName: String? = null
|
||||
for (i in 0 until xpp.attributeCount) {
|
||||
when (xpp.getAttributeName(i)) {
|
||||
"component" -> componentName = xpp.getAttributeValue(i)
|
||||
"drawable" -> drawableName = xpp.getAttributeValue(i)
|
||||
}
|
||||
}
|
||||
for (i in 0 until xpp.attributeCount) { when (xpp.getAttributeName(i)) {
|
||||
"component" -> componentName = xpp.getAttributeValue(i)
|
||||
"drawable" -> drawableName = xpp.getAttributeValue(i)
|
||||
} }
|
||||
if (!packagesDrawables.containsKey(componentName)) {
|
||||
packagesDrawables[componentName] = drawableName
|
||||
totalIcons += 1
|
||||
@ -127,12 +126,30 @@ internal class IconPackManager {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
|
||||
val cacheSize = maxMemory / 8
|
||||
val bitmapCache = object : LruCache<String, Bitmap>(cacheSize) {
|
||||
fun sizeOf(key: String?, value: Bitmap?): Int {
|
||||
return if(value?.byteCount?.toInt() ?: 0 > 1024) {
|
||||
value?.byteCount!!.div(1024)
|
||||
} else { 0 }
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadBitmap(drawableName: String): Bitmap? {
|
||||
if (packageName != null && packageName.length > 0) {
|
||||
var bm = bitmapCache.get(packageName)
|
||||
if (bm != null) return bm
|
||||
}
|
||||
iconPackRes!!.getIdentifier(drawableName, "drawable", packageName).let { id ->
|
||||
if (id > 0) {
|
||||
ResourcesCompat.getDrawable(iconPackRes!!, id, null).let {
|
||||
if (it is BitmapDrawable) return it.bitmap
|
||||
if (it is BitmapDrawable) {
|
||||
if (packageName != null && packageName.length > 0) {
|
||||
bitmapCache.put(packageName, it.bitmap)
|
||||
}
|
||||
return it.bitmap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,35 +163,69 @@ internal class IconPackManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun getDrawableIconForPackage(appPackageName: String?, defaultDrawable: Drawable?): Drawable? {
|
||||
when (packageName) {
|
||||
DEFAULT_ICON_PACK -> return defaultDrawable
|
||||
else -> {
|
||||
if (!loaded) load()
|
||||
var componentName: String? = null
|
||||
if (lActivity!!.packageManager.getLaunchIntentForPackage(appPackageName!!) != null) {
|
||||
componentName = lActivity!!.packageManager.getLaunchIntentForPackage(appPackageName)!!.component.toString()
|
||||
}
|
||||
var drawable = packagesDrawables[componentName]
|
||||
if (!drawable.isNullOrEmpty()) return loadDrawable(drawable)
|
||||
else {
|
||||
/* try to get a resource with the component filename */
|
||||
if (!componentName.isNullOrEmpty()) {
|
||||
val start = componentName.indexOf("{") + 1
|
||||
val end = componentName.indexOf("}", start)
|
||||
if (end > start) {
|
||||
drawable = componentName.substring(start, end).lowercase(Locale.getDefault()).replace(".", "_").replace("/", "_")
|
||||
try {
|
||||
if (iconPackRes!!.getIdentifier(drawable, "drawable", packageName) > 0) return loadDrawable(drawable)
|
||||
} catch (e: NullPointerException) {
|
||||
settingsPrefs.edit().putString(KEY_ICON_PACK, DEFAULT_ICON_PACK).apply()
|
||||
fun putAfterReturn(packages: String, drawable : Drawable?) : Drawable? {
|
||||
if (drawable != null) {
|
||||
appPackageIconDrawables.put(packages, drawable)
|
||||
}
|
||||
return drawable
|
||||
}
|
||||
|
||||
fun getDrawableIconForPackage(appPackageName: String?, defaultDrawable: Drawable?, onComplete : (Drawable?)->Unit) {
|
||||
var ddd = if (appPackageIconDrawables.containsKey(appPackageName)) appPackageIconDrawables.get(appPackageName) else null
|
||||
if (ddd != null) {
|
||||
onComplete(ddd)
|
||||
} else {
|
||||
when (packageName) {
|
||||
DEFAULT_ICON_PACK -> onComplete.invoke(defaultDrawable)
|
||||
else -> {
|
||||
if (!loaded) load()
|
||||
var componentName: String? = null
|
||||
componentName = packagesConponentNames.get(appPackageName!!)
|
||||
if (componentName == null || componentName.length ?: 0 <= 0 ) {
|
||||
BLog.LOGE("it's compo ${appPackageName}")
|
||||
var pkgIntent =
|
||||
lActivity!!.packageManager.getLaunchIntentForPackage(
|
||||
appPackageName!!
|
||||
)
|
||||
if (pkgIntent != null) {
|
||||
componentName = pkgIntent!!.component.toString()
|
||||
}
|
||||
}
|
||||
var drawable = packagesDrawables[componentName]
|
||||
if (!drawable.isNullOrEmpty()) onComplete.invoke(
|
||||
putAfterReturn(
|
||||
appPackageName,
|
||||
loadDrawable(drawable)
|
||||
)
|
||||
)
|
||||
else {
|
||||
if (!componentName.isNullOrEmpty()) {
|
||||
val start = componentName.indexOf("{") + 1
|
||||
val end = componentName.indexOf("}", start)
|
||||
if (end > start) {
|
||||
drawable = componentName.substring(start, end)
|
||||
.lowercase(Locale.getDefault()).replace(".", "_")
|
||||
.replace("/", "_")
|
||||
try {
|
||||
if (iconPackRes!!.getIdentifier(
|
||||
drawable,
|
||||
"drawable",
|
||||
packageName
|
||||
) > 0
|
||||
) onComplete.invoke(putAfterReturn(appPackageName, loadDrawable(drawable)))
|
||||
} catch (e: NullPointerException) {
|
||||
settingsPrefs.edit()
|
||||
.putString(KEY_ICON_PACK, DEFAULT_ICON_PACK).apply()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
onComplete.invoke(defaultDrawable)
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultDrawable
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -32,4 +32,5 @@ internal class WidgetHost(context: Context, hostId: Int) : AppWidgetHost(context
|
||||
clearViews()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -36,7 +36,6 @@ internal class WidgetHostView(context: Context) : AppWidgetHostView(context) {
|
||||
hasPerformedLongPress = false
|
||||
return true
|
||||
}
|
||||
|
||||
// Watch for long press events at this level to make sure
|
||||
// users can always pick up this widget
|
||||
when (ev.action) {
|
||||
|
||||
@ -212,11 +212,11 @@ internal class UniUtils {
|
||||
(iconSize * resources.displayMetrics.density).toInt(), 1F)
|
||||
}.let { sImageView ->
|
||||
context.packageManager.getApplicationIcon(packageName).let { defaultIcon ->
|
||||
sImageView.setImageDrawable(
|
||||
if (context.getSharedPreferences(PREFS_SETTINGS, 0).getInt(KEY_APPS_LAYOUT, 0) != 0)
|
||||
getDrawableIconForPackage(packageName, defaultIcon)
|
||||
else defaultIcon
|
||||
)
|
||||
getDrawableIconForPackage(packageName, defaultIcon) {
|
||||
sImageView.setImageDrawable(it ?: defaultIcon)
|
||||
}
|
||||
else sImageView.setImageDrawable(defaultIcon)
|
||||
}
|
||||
sImageView.setOnClickListener {
|
||||
context.startActivity(context.packageManager.getLaunchIntentForPackage(packageName))
|
||||
|
||||
@ -26,6 +26,7 @@ import android.provider.Settings
|
||||
import android.view.animation.AnimationUtils
|
||||
import com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
import rasel.lunar.launcher.R
|
||||
import rasel.lunar.launcher.utils.BLog
|
||||
|
||||
|
||||
internal class BatteryReceiver(private val progressBar: CircularProgressIndicator) : BroadcastReceiver() {
|
||||
@ -42,7 +43,14 @@ internal class BatteryReceiver(private val progressBar: CircularProgressIndicato
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
val animationDuration = try {
|
||||
Settings.Global.getFloat(context?.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE)
|
||||
intent?.extras?.keySet()?.let {
|
||||
it.iterator().forEach {
|
||||
BLog.LOGE("intent key >> ${it}")
|
||||
}
|
||||
}
|
||||
BLog.LOGE("intent >> ${intent}")
|
||||
|
||||
Settings.Global.getFloat(context?.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f)
|
||||
} catch (e: Settings.SettingNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
@ -134,12 +134,7 @@ internal class LauncherHome : Fragment() {
|
||||
gestureDistance: Double
|
||||
): Boolean {
|
||||
when(fingers) {
|
||||
1 ->
|
||||
if (targetView?.equals(binding.batteryProgress) ?: false) {
|
||||
QuickAccess().show(fragManager, BOTTOM_SHEET_TAG)
|
||||
} else {
|
||||
QuickAccess().show(fragManager, BOTTOM_SHEET_TAG)
|
||||
}
|
||||
3 -> QuickAccess().show(fragManager, BOTTOM_SHEET_TAG)
|
||||
2->{
|
||||
var startIntene = Intent(Intent.ACTION_MAIN)
|
||||
startIntene.setComponent(ComponentName("com.mime.dualscreenview","com.mime.dualscreenview.activity.Intro"))
|
||||
@ -215,11 +210,7 @@ internal class LauncherHome : Fragment() {
|
||||
override fun onDoubleTap(targetView: View,fingers: Int): Boolean {
|
||||
|
||||
when(fingers) {
|
||||
1 -> if (targetView?.equals(binding.batteryProgress) ?: false) {
|
||||
lockMethod(settingsPrefs.getInt(KEY_LOCK_METHOD, 0), requireContext(), binding.favAppsGroup)
|
||||
} else {
|
||||
lockMethod(settingsPrefs.getInt(KEY_LOCK_METHOD, 0), requireContext(), binding.favAppsGroup)
|
||||
}
|
||||
1 -> lockMethod(settingsPrefs.getInt(KEY_LOCK_METHOD, 0), requireContext(), binding.favAppsGroup)
|
||||
else -> {}
|
||||
}
|
||||
return false
|
||||
|
||||
@ -35,6 +35,10 @@ import java.util.concurrent.Executors
|
||||
|
||||
internal class WeatherExecutor(sharedPreferences: SharedPreferences) {
|
||||
|
||||
companion object {
|
||||
var lastedCheckTime = 0L
|
||||
}
|
||||
|
||||
private val cityName: String
|
||||
private val owmApi: String
|
||||
private val weatherUrl: String
|
||||
@ -44,10 +48,9 @@ internal class WeatherExecutor(sharedPreferences: SharedPreferences) {
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun generateWeatherString(materialTextView: MaterialTextView) {
|
||||
materialTextView.visibility = View.GONE
|
||||
|
||||
/* run the executor if network is available,
|
||||
and city name and owm api values are not empty */
|
||||
if (isNetworkAvailable && cityName.isNotEmpty() && owmApi.isNotEmpty()) {
|
||||
if (System.currentTimeMillis() - lastedCheckTime > (1000 * 60 * 15) && isNetworkAvailable && cityName.isNotEmpty() && owmApi.isNotEmpty()) {
|
||||
try {
|
||||
Executors.newSingleThreadExecutor().execute {
|
||||
var weather: Weather? = null
|
||||
@ -70,6 +73,7 @@ internal class WeatherExecutor(sharedPreferences: SharedPreferences) {
|
||||
exception.printStackTrace()
|
||||
}
|
||||
}
|
||||
lastedCheckTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
init {
|
||||
@ -77,7 +81,7 @@ internal class WeatherExecutor(sharedPreferences: SharedPreferences) {
|
||||
owmApi = sharedPreferences.getString(KEY_OWM_API, "").toString()
|
||||
tempUnit = sharedPreferences.getInt(KEY_TEMP_UNIT, 0)
|
||||
showCity = sharedPreferences.getBoolean(KEY_SHOW_CITY, false)
|
||||
weatherUrl = URLEncoder.encode("https://api.openweathermap.org/data/2.5/weather?q=$cityName&APPID=$owmApi&units=" + if (tempUnit == 0) "metric" else "imperial","utf-8")
|
||||
weatherUrl = "https://api.openweathermap.org/data/2.5/weather?q=$cityName&APPID=$owmApi&units=" + if (tempUnit == 0) "metric" else "imperial"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ internal class Apps : BottomSheetDialogFragment() {
|
||||
Gravity.RIGHT -> binding.appAlignmentRight.isChecked = true
|
||||
}
|
||||
|
||||
binding.columnsCount.value = settingsPrefs!!.getInt(KEY_GRID_COLUMNS, DEFAULT_GRID_COLUMNS).toFloat()
|
||||
binding.columnsCount.value = Math.min(settingsPrefs!!.getInt(KEY_GRID_COLUMNS, DEFAULT_GRID_COLUMNS).toFloat(), 4f)
|
||||
binding.scrollbarHeight.value = settingsPrefs!!.getInt(KEY_SCROLLBAR_HEIGHT, DEFAULT_SCROLLBAR_HEIGHT).toFloat()
|
||||
|
||||
return binding.root
|
||||
|
||||
@ -7,37 +7,39 @@
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/appsCount"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:textColor="?attr/colorControlHighlight"
|
||||
android:textSize="@dimen/appsCountText"
|
||||
android:gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/appsList"
|
||||
app:layout_constraintStart_toStartOf="@id/appsList"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/appsList"
|
||||
android:layout_width="@dimen/zero"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:fadingEdgeLength="@dimen/sixteen"
|
||||
android:overScrollMode="never"
|
||||
android:requiresFadingEdge="vertical"
|
||||
android:scrollbars="none"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/searchInput"
|
||||
app:layout_constraintEnd_toStartOf="@+id/search"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<rasel.lunar.launcher.apps.AlphabetScrollbar
|
||||
android:id="@+id/alphabets"
|
||||
android:layout_width="@dimen/zero"
|
||||
android:visibility="gone"
|
||||
android:layout_height="@dimen/zero"
|
||||
android:layout_marginBottom="@dimen/four"
|
||||
app:layout_constraintBottom_toTopOf="@+id/reset"
|
||||
app:layout_constraintStart_toStartOf="@id/reset"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
<!-- <rasel.lunar.launcher.apps.AlphabetScrollbar-->
|
||||
<!-- android:id="@+id/alphabets"-->
|
||||
<!-- android:layout_width="@dimen/zero"-->
|
||||
<!-- android:visibility="gone"-->
|
||||
<!-- android:layout_height="@dimen/zero"-->
|
||||
<!-- android:layout_marginBottom="@dimen/four"-->
|
||||
<!-- app:layout_constraintBottom_toTopOf="@+id/reset"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="@id/reset"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent" />-->
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/reset"
|
||||
@ -84,13 +86,13 @@
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/searchInput"
|
||||
android:layout_width="@dimen/oneThirtySix"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:imeOptions="actionSearch"
|
||||
android:singleLine="true"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/appsList"
|
||||
app:layout_constraintStart_toStartOf="@+id/appsList" />
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@ -1,30 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="@drawable/apps_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/appIcon"
|
||||
android:id="@+id/appIconTwo"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_width="@dimen/forty"
|
||||
android:layout_height="@dimen/forty"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="@dimen/four" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginBottom="@dimen/four"
|
||||
android:visibility="visible"
|
||||
android:id="@+id/appIcon"
|
||||
android:layout_width="@dimen/forty"
|
||||
android:layout_height="@dimen/forty" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/childTextview"
|
||||
app:layout_constraintTop_toBottomOf="@id/appIconTwo"
|
||||
app:layout_constraintLeft_toRightOf="@id/appIcon"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_marginBottom="@dimen/four"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/appIconTwo"
|
||||
android:layout_width="@dimen/forty"
|
||||
android:layout_height="@dimen/forty" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/childTextview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@ -231,8 +231,8 @@
|
||||
android:id="@+id/columnsCount"
|
||||
android:layout_width="@dimen/zero"
|
||||
android:layout_height="wrap_content"
|
||||
android:valueFrom="3"
|
||||
android:valueTo="7"
|
||||
android:valueFrom="2"
|
||||
android:valueTo="5"
|
||||
android:stepSize="1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user