Merge branch 'main' of https://dev.lunaticbum.kr/lun_admin/lun_launcher
# Conflicts: # app/src/main/kotlin/rasel/lunar/launcher/apps/AppDrawer.kt
This commit is contained in:
commit
ed24af2d41
@ -18,6 +18,7 @@
|
|||||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
|
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
|
||||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
|
||||||
<!-- api 33+ -->
|
<!-- api 33+ -->
|
||||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
|
|||||||
@ -27,7 +27,10 @@ import android.graphics.Color
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.CallLog
|
||||||
|
import android.provider.ContactsContract
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
|
import android.util.Log
|
||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
@ -44,11 +47,12 @@ import androidx.viewpager2.widget.ViewPager2
|
|||||||
import com.google.android.material.color.DynamicColors
|
import com.google.android.material.color.DynamicColors
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import rasel.lunar.launcher.apps.AppDrawer
|
import rasel.lunar.launcher.apps.AppDrawer
|
||||||
|
import rasel.lunar.launcher.apps.DismissCalback
|
||||||
|
import rasel.lunar.launcher.apps.SearchMenu
|
||||||
import rasel.lunar.launcher.databinding.LauncherActivityBinding
|
import rasel.lunar.launcher.databinding.LauncherActivityBinding
|
||||||
import rasel.lunar.launcher.feeds.Feeds
|
import rasel.lunar.launcher.feeds.Feeds
|
||||||
import rasel.lunar.launcher.feeds.WidgetHost
|
import rasel.lunar.launcher.feeds.WidgetHost
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_BACK_HOME
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_FIRST_LAUNCH
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_FIRST_LAUNCH
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_STATUS_BAR
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WINDOW_BACKGROUND
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_WINDOW_BACKGROUND
|
||||||
@ -59,6 +63,7 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.getColorResId
|
|||||||
import rasel.lunar.launcher.helpers.ViewPagerAdapter
|
import rasel.lunar.launcher.helpers.ViewPagerAdapter
|
||||||
import rasel.lunar.launcher.home.LauncherHome
|
import rasel.lunar.launcher.home.LauncherHome
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
|
||||||
internal class LauncherActivity : AppCompatActivity() {
|
internal class LauncherActivity : AppCompatActivity() {
|
||||||
@ -152,7 +157,10 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
private fun setupView() {
|
private fun setupView() {
|
||||||
viewPager = binding.viewPager.apply {
|
viewPager = binding.viewPager.apply {
|
||||||
adapter = ViewPagerAdapter(
|
adapter = ViewPagerAdapter(
|
||||||
supportFragmentManager, mutableListOf(Feeds(), LauncherHome(), AppDrawer()), lifecycle)
|
supportFragmentManager,
|
||||||
|
mutableListOf(Feeds(), LauncherHome(), AppDrawer()),
|
||||||
|
lifecycle
|
||||||
|
)
|
||||||
offscreenPageLimit = 1
|
offscreenPageLimit = 1
|
||||||
setCurrentItem(1, false)
|
setCurrentItem(1, false)
|
||||||
reduceDragSensitivity()
|
reduceDragSensitivity()
|
||||||
@ -227,4 +235,9 @@ internal class LauncherActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun openSearchMenus(keyword : String, dismissCalback: DismissCalback) {
|
||||||
|
SearchMenu().show(supportFragmentManager,keyword) {dismissCalback?.invoke()}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -28,9 +28,11 @@ import android.content.pm.ResolveInfo
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.Gravity
|
import android.view.KeyEvent.ACTION_UP
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
@ -42,16 +44,12 @@ import androidx.core.widget.doOnTextChanged
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.MainScope
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import rasel.lunar.launcher.BuildConfig
|
import rasel.lunar.launcher.BuildConfig
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
import rasel.lunar.launcher.databinding.AppDrawerBinding
|
import rasel.lunar.launcher.databinding.AppDrawerBinding
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_COUNT
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_COUNT
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_LAYOUT
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPS_LAYOUT
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_DRAW_ALIGN
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_KEYBOARD_SEARCH
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_QUICK_LAUNCH
|
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_APP_NAMES
|
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_APP_NAMES
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_SETTINGS
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
@ -63,7 +61,7 @@ internal class AppDrawer : Fragment() {
|
|||||||
|
|
||||||
private lateinit var binding: AppDrawerBinding
|
private lateinit var binding: AppDrawerBinding
|
||||||
private var layoutType: Int = 0
|
private var layoutType: Int = 0
|
||||||
private var isSearchShown: Boolean = false
|
// private var isSearchShown: Boolean = false
|
||||||
private var isKeyboardShowing: Boolean = false
|
private var isKeyboardShowing: Boolean = false
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -226,6 +224,7 @@ internal class AppDrawer : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun openSearchApps(schemeString : String, pakage : String? = null) {
|
fun openSearchApps(schemeString : String, pakage : String? = null) {
|
||||||
val gmmIntentUri = Uri.parse(schemeString)
|
val gmmIntentUri = Uri.parse(schemeString)
|
||||||
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
@ -238,24 +237,6 @@ internal class AppDrawer : Fragment() {
|
|||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
binding.reset.setOnClickListener { filterAppsList("") }
|
|
||||||
|
|
||||||
// binding.moveDown.setOnClickListener {
|
|
||||||
// binding.appsList.smoothScrollToPosition(packageList.size - 1)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// binding.moveUp.setOnClickListener {
|
|
||||||
// binding.appsList.smoothScrollToPosition(0)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// binding.search.setOnClickListener {
|
|
||||||
// when (isSearchShown) {
|
|
||||||
// true -> closeSearch()
|
|
||||||
// false -> openSearch()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
binding.searchInput.setOnKeyListener { v, keyCode, event ->
|
binding.searchInput.setOnKeyListener { v, keyCode, event ->
|
||||||
if (keyCode == 66 && contactList.size < 1 && packageList.size < 1) {
|
if (keyCode == 66 && contactList.size < 1 && packageList.size < 1) {
|
||||||
binding.searchGoogle.performClick()
|
binding.searchGoogle.performClick()
|
||||||
@ -270,20 +251,144 @@ internal class AppDrawer : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun checkResult(keyword: String) {
|
||||||
|
|
||||||
|
if(!isAdded || !isResumed || keyword.length < 1) return
|
||||||
|
var dialog : AlertDialog.Builder? = null
|
||||||
|
var filted = packageList.filter { it.appName.equals(keyword) }
|
||||||
|
BLog.LOGE("filted >> ${filted.size}")
|
||||||
|
var filtedContact = contactList.filter { it.name.equals(keyword) }
|
||||||
|
BLog.LOGE("filtedContact >> ${filtedContact.size}")
|
||||||
|
if (keyword.length > 0 && (packageList.size == 1 || filted.size > 0)) {
|
||||||
|
dialog = AlertDialog.Builder(requireContext())
|
||||||
|
dialog?.setTitle("앱 실행 확인")
|
||||||
|
if (packageList.size == 1) {
|
||||||
|
dialog?.setMessage("${keyword} 검색 결과 '${packageList[0].appName}' 준비됨")
|
||||||
|
dialog?.setPositiveButton("실행") { s, d ->
|
||||||
|
runonUi {
|
||||||
|
startActivity(packageManager?.getLaunchIntentForPackage(packageList[0].packageName))
|
||||||
|
s.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (filted.size > 0) {
|
||||||
|
dialog?.setMessage("${keyword} 검색 결과 '${filted[0].appName}' 준비됨")
|
||||||
|
dialog?.setPositiveButton("${filted[0].appName} 실행") { s, d ->
|
||||||
|
runonUi {
|
||||||
|
startActivity(packageManager?.getLaunchIntentForPackage(filted[0].packageName))
|
||||||
|
s.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(filted.size > 1) {
|
||||||
|
dialog?.setNeutralButton("${filted[1].appName} 실행") { s, d ->
|
||||||
|
runonUi {
|
||||||
|
startActivity(packageManager?.getLaunchIntentForPackage(filted[1].packageName))
|
||||||
|
s.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialog?.setCancelable(false)
|
||||||
|
dialog?.setNegativeButton("취소") { s, d ->
|
||||||
|
runonUi { s.dismiss() }
|
||||||
|
}
|
||||||
|
dialog?.setOnDismissListener { registCancelSearch() }
|
||||||
|
dialog?.show()
|
||||||
|
} else if (contactList.size == 1 || filtedContact.size > 0) {
|
||||||
|
dialog = AlertDialog.Builder(requireContext())
|
||||||
|
dialog?.setTitle("연락처 실행 확인")
|
||||||
|
dialog?.setCancelable(false)
|
||||||
|
dialog?.setNegativeButton("취소") { s, d ->
|
||||||
|
runonUi { s.dismiss() }
|
||||||
|
}
|
||||||
|
if (contactList.size == 1) {
|
||||||
|
dialog?.setMessage("${keyword} 검색 결과 '${contactList[0].name}' 준비됨")
|
||||||
|
dialog?.setPositiveButton("자세히 보기") { s, d ->
|
||||||
|
runonUi {
|
||||||
|
ContactMenu().show(childFragmentManager, contactList[0].id.toString())
|
||||||
|
s.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(filtedContact.size > 0) {
|
||||||
|
dialog?.setMessage("${keyword} 검색 결과 '${filtedContact[0].name}' 준비됨")
|
||||||
|
dialog?.setPositiveButton("'${filtedContact[0].name},\n${filtedContact[0].phoneNumber}'\n자세히 보기") { s, d ->
|
||||||
|
runonUi {
|
||||||
|
ContactMenu().show(childFragmentManager, filtedContact[0].id.toString())
|
||||||
|
s.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (filtedContact.size > 1) {
|
||||||
|
dialog?.setNeutralButton("'${filtedContact[1].name},\n${filtedContact[1].phoneNumber}'\n자세히 보기") { s, d ->
|
||||||
|
runonUi {
|
||||||
|
ContactMenu().show(childFragmentManager, filtedContact[1].id.toString())
|
||||||
|
s.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialog?.setOnDismissListener { registCancelSearch() }
|
||||||
|
dialog?.show()
|
||||||
|
} else {
|
||||||
|
lActivity?.openSearchMenus(keyword) {
|
||||||
|
registCancelSearch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun runonUi(invoke : () -> Unit) {
|
||||||
|
Handler(Looper.getMainLooper()).run {
|
||||||
|
try {
|
||||||
|
invoke.invoke()
|
||||||
|
}catch (e : Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
BLog.LOGE("onResume")
|
||||||
fetchApps()
|
fetchApps()
|
||||||
GetContact()
|
GetContact()
|
||||||
|
|
||||||
binding.appsCount.visibility = if (settingsPrefs!!.getBoolean(KEY_APPS_COUNT, true)) VISIBLE else GONE
|
binding.appsCount.visibility = if (settingsPrefs!!.getBoolean(KEY_APPS_COUNT, true)) VISIBLE else GONE
|
||||||
|
|
||||||
if (settingsPrefs!!.getInt(KEY_APPS_LAYOUT, 0) in 0..1) {
|
// if (settingsPrefs!!.getInt(KEY_APPS_LAYOUT, 0) in 0..1) {
|
||||||
appsAdapter?.updateGravity(settingsPrefs!!.getInt(KEY_DRAW_ALIGN, Gravity.CENTER))
|
// appsAdapter?.updateGravity(settingsPrefs!!.getInt(KEY_DRAW_ALIGN, Gravity.CENTER))
|
||||||
}
|
// }
|
||||||
|
|
||||||
contactAdapter?.updateData(contactList)
|
contactAdapter?.updateData(contactList)
|
||||||
|
|
||||||
openSearch()
|
openSearch()
|
||||||
|
setKeyboardPadding()
|
||||||
|
|
||||||
|
contactAdapter?.updateData(contactList)
|
||||||
|
|
||||||
|
/* pop up the keyboard */
|
||||||
|
openSearch()
|
||||||
|
|
||||||
|
registCancelSearch()
|
||||||
|
BLog.LOGE("onResume after chechHandler.postDelayed(cancelSearch, 3000L)")
|
||||||
|
}
|
||||||
|
|
||||||
|
val chechHandler = Handler(Looper.getMainLooper())
|
||||||
|
|
||||||
|
val cancelSearch = Runnable { timerCheck() }
|
||||||
|
|
||||||
|
fun registCancelSearch() {
|
||||||
|
BLog.LOGE("Called registCancelSearch")
|
||||||
|
chechHandler.removeCallbacks(cancelSearch)
|
||||||
|
chechHandler.postDelayed(cancelSearch, 3000L)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearCancelSearch() {
|
||||||
|
chechHandler.removeCallbacks(cancelSearch)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun timerCheck() {
|
||||||
|
lActivity?.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
@ -308,12 +413,6 @@ internal class AppDrawer : Fragment() {
|
|||||||
|
|
||||||
/* update app list with app and package name */
|
/* update app list with app and package name */
|
||||||
fun fetchApps() {
|
fun fetchApps() {
|
||||||
if (oringinPackageList.size > 0) {
|
|
||||||
packageList.clear()
|
|
||||||
for(pkg in oringinPackageList) {
|
|
||||||
packageList.add(pkg)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
packageList.clear()
|
packageList.clear()
|
||||||
oringinPackageList.clear()
|
oringinPackageList.clear()
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
@ -328,42 +427,16 @@ internal class AppDrawer : Fragment() {
|
|||||||
))
|
))
|
||||||
})?.apply {
|
})?.apply {
|
||||||
removeIf { it.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID) }
|
removeIf { it.activityInfo.packageName.equals(BuildConfig.APPLICATION_ID) }
|
||||||
|
forEach { oringinPackageList.add(Packages(it.activityInfo.packageName, normalize(appName(it)), getCategory(it.activityInfo.applicationInfo.category))) }
|
||||||
forEach {
|
oringinPackageList.sortBy { it.appName }
|
||||||
oringinPackageList.add(
|
packageList.addAll(
|
||||||
Packages(
|
oringinPackageList
|
||||||
it.activityInfo.packageName,
|
|
||||||
appName(it),
|
|
||||||
getCategory(it.activityInfo.applicationInfo.category)
|
|
||||||
)
|
)
|
||||||
)
|
binding.appsList.post { if (packageList.size > 0) {
|
||||||
packageList.add(
|
appsAdapter?.updateData(packageList)
|
||||||
Packages(
|
} }
|
||||||
it.activityInfo.packageName,
|
|
||||||
appName(it),
|
|
||||||
getCategory(it.activityInfo.applicationInfo.category)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}!!
|
}!!
|
||||||
}
|
}
|
||||||
/* add package and app names to the list */
|
|
||||||
|
|
||||||
// var edit = appNamesPrefs?.edit()
|
|
||||||
// for (resolver in packageInfoList) {
|
|
||||||
// packageList.add(Packages(resolver.activityInfo.packageName, appName(resolver)))
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
// when {
|
|
||||||
// packageList.size < 1 -> return
|
|
||||||
// else -> {
|
|
||||||
if (packageList.size > 0) {
|
|
||||||
MainScope().launch {
|
|
||||||
appsAdapter?.updateData(packageList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAlphabetItems() {
|
private fun getAlphabetItems() {
|
||||||
@ -395,7 +468,7 @@ internal class AppDrawer : Fragment() {
|
|||||||
var lastSearchString : String = ""
|
var lastSearchString : String = ""
|
||||||
private fun filterAppsList(searchString: String) {
|
private fun filterAppsList(searchString: String) {
|
||||||
/* check each app name and add if it matches the search string */
|
/* check each app name and add if it matches the search string */
|
||||||
if (lastSearchStringLength > 0 && (lastSearchStringLength != searchString.length || lastSearchString.equals(searchString) == false)) {
|
if (searchString.length > 0 && (lastSearchStringLength != searchString.length || lastSearchString.equals(searchString) == false)) {
|
||||||
BLog.LOGE("START FILTER")
|
BLog.LOGE("START FILTER")
|
||||||
packageList.clear()
|
packageList.clear()
|
||||||
for (pkg in oringinPackageList) {
|
for (pkg in oringinPackageList) {
|
||||||
@ -404,38 +477,22 @@ internal class AppDrawer : Fragment() {
|
|||||||
packageList.add(pkg)
|
packageList.add(pkg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
packageList.sortBy { it.appName }
|
||||||
BLog.LOGE("MIDDLE FILTER")
|
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)
|
appsAdapter?.updateData(packageList)
|
||||||
}
|
|
||||||
contactList.clear()
|
contactList.clear()
|
||||||
for (item in originContactList) {
|
for (item in originContactList) {
|
||||||
if (item.name.contains(searchString) || item.phoneNumber.contains(searchString)) {
|
if (item.name.contains(searchString) || item.phoneNumber.contains(searchString)) {
|
||||||
contactList.add(item)
|
contactList.add(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
contactList.sortBy { it.name }
|
||||||
contactAdapter?.updateData(contactList)
|
contactAdapter?.updateData(contactList)
|
||||||
BLog.LOGE("END FILTER")
|
BLog.LOGE("END FILTER")
|
||||||
|
|
||||||
|
|
||||||
} else if(lastSearchStringLength == 0){
|
} else if(lastSearchStringLength == 0){
|
||||||
contactList.clear()
|
contactList.clear()
|
||||||
for (item in originContactList) {
|
for (item in originContactList) {
|
||||||
@ -447,9 +504,28 @@ internal class AppDrawer : Fragment() {
|
|||||||
}
|
}
|
||||||
appsAdapter?.updateData(packageList)
|
appsAdapter?.updateData(packageList)
|
||||||
contactAdapter?.updateData(contactList)
|
contactAdapter?.updateData(contactList)
|
||||||
|
} else {
|
||||||
|
afterClearSearch()
|
||||||
|
|
||||||
}
|
}
|
||||||
lastSearchString = searchString
|
lastSearchString = searchString
|
||||||
lastSearchStringLength = searchString.length
|
lastSearchStringLength = searchString.length
|
||||||
|
registCancelSearch()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun afterClearSearch() {
|
||||||
|
contactList.clear()
|
||||||
|
packageList.clear()
|
||||||
|
for (item in originContactList) {
|
||||||
|
contactList.add(item)
|
||||||
|
}
|
||||||
|
for (resolver in oringinPackageList) {
|
||||||
|
packageList.add(resolver)
|
||||||
|
}
|
||||||
|
packageList.sortBy { it.appName }
|
||||||
|
contactList.sortBy { it.name }
|
||||||
|
appsAdapter?.updateData(packageList)
|
||||||
|
contactAdapter?.updateData(contactList)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun normalize(str: String): String {
|
private fun normalize(str: String): String {
|
||||||
@ -460,26 +536,21 @@ internal class AppDrawer : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun openSearch() {
|
private fun openSearch() {
|
||||||
isSearchShown = true
|
|
||||||
binding.searchInput.apply {
|
binding.searchInput.apply {
|
||||||
visibility = VISIBLE
|
visibility = VISIBLE
|
||||||
requestFocus()
|
requestFocus()
|
||||||
let {
|
let {
|
||||||
(lActivity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
|
(lActivity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.showSoftInput(it, InputMethodManager.SHOW_IMPLICIT)
|
||||||
.showSoftInput(it, InputMethodManager.SHOW_IMPLICIT)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear search string, hide keyboard and search box */
|
/* clear search string, hide keyboard and search box */
|
||||||
private fun closeSearch() {
|
private fun closeSearch() {
|
||||||
isSearchShown = false
|
|
||||||
binding.searchInput.apply {
|
binding.searchInput.apply {
|
||||||
text?.clear()
|
|
||||||
visibility = GONE
|
|
||||||
let {
|
let {
|
||||||
(lActivity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
|
text?.clear()
|
||||||
.hideSoftInputFromWindow(it.windowToken, 0)
|
(lActivity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.hideSoftInputFromWindow(it.windowToken, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ internal class AppsAdapter(
|
|||||||
private val appsCount: TextView) : RecyclerView.Adapter<AppsAdapter.AppsViewHolder>() {
|
private val appsCount: TextView) : RecyclerView.Adapter<AppsAdapter.AppsViewHolder>() {
|
||||||
|
|
||||||
private var oldList = mutableListOf<Packages>()
|
private var oldList = mutableListOf<Packages>()
|
||||||
private var appGravity: Int = Gravity.CENTER
|
// private var appGravity: Int = Gravity.CENTER
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic var appsSize: Int? = null
|
@JvmStatic var appsSize: Int? = null
|
||||||
@ -106,21 +106,6 @@ internal class AppsAdapter(
|
|||||||
appsSize = it
|
appsSize = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update text gravity (alignment) */
|
|
||||||
@SuppressLint("RtlHardcoded", "NotifyDataSetChanged")
|
|
||||||
fun updateGravity(gravity: Int){
|
|
||||||
/* the first check is to avoid calling notifyDataSetChanged() everytime */
|
|
||||||
if (gravity != appGravity &&
|
|
||||||
(gravity == Gravity.LEFT || gravity == Gravity.CENTER || gravity == Gravity.RIGHT)) {
|
|
||||||
appGravity = gravity
|
|
||||||
notifyDataSetChanged()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun hideItem(idx: Int) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Packages (
|
data class Packages (
|
||||||
|
|||||||
@ -70,7 +70,7 @@ internal class ContactAdapter (
|
|||||||
holder.view.root.apply {
|
holder.view.root.apply {
|
||||||
/* on click - open app */
|
/* on click - open app */
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
context.startActivity(Intent(Intent.ACTION_DIAL, Uri.parse("tel://${item.phoneNumber}")))
|
ContactMenu().show(fragmentManager, item.id.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
/* on long click - open app menu */
|
/* on long click - open app menu */
|
||||||
|
|||||||
@ -58,6 +58,7 @@ import rasel.lunar.launcher.apps.AppDrawer.Companion.appNamesPrefs
|
|||||||
import rasel.lunar.launcher.databinding.ActivityBrowserDialogBinding
|
import rasel.lunar.launcher.databinding.ActivityBrowserDialogBinding
|
||||||
import rasel.lunar.launcher.databinding.AppInfoDialogBinding
|
import rasel.lunar.launcher.databinding.AppInfoDialogBinding
|
||||||
import rasel.lunar.launcher.databinding.AppMenuBinding
|
import rasel.lunar.launcher.databinding.AppMenuBinding
|
||||||
|
import rasel.lunar.launcher.databinding.ContactMenuBinding
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APP_NO_
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APP_NO_
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.MAX_FAVORITE_APPS
|
import rasel.lunar.launcher.helpers.Constants.Companion.MAX_FAVORITE_APPS
|
||||||
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FAVORITE_APPS
|
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FAVORITE_APPS
|
||||||
@ -74,14 +75,15 @@ import java.util.*
|
|||||||
|
|
||||||
internal class ContactMenu : BottomSheetDialogFragment() {
|
internal class ContactMenu : BottomSheetDialogFragment() {
|
||||||
|
|
||||||
private lateinit var binding: AppMenuBinding
|
private lateinit var binding: ContactMenuBinding
|
||||||
private lateinit var packageName: String
|
private lateinit var packageName: String
|
||||||
private lateinit var packageManager: PackageManager
|
private lateinit var packageManager: PackageManager
|
||||||
private lateinit var appInfo: ApplicationInfo
|
private lateinit var appInfo: ApplicationInfo
|
||||||
private lateinit var defAppName: String
|
private lateinit var defAppName: String
|
||||||
|
var contactName : String = ""
|
||||||
|
var contactPhoneNumber : String = ""
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
binding = AppMenuBinding.inflate(inflater, container, false)
|
binding = ContactMenuBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
/* get package name from fragment's tag */
|
/* get package name from fragment's tag */
|
||||||
packageName = tag.toString()
|
packageName = tag.toString()
|
||||||
@ -96,14 +98,12 @@ internal class ContactMenu : BottomSheetDialogFragment() {
|
|||||||
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
|
val cursor = resolver.query(phoneUri, projection, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + packageName, null , null)
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
// val idx =cursor.getColumnIndex(projection[0])
|
|
||||||
val nameIndex = cursor.getColumnIndex(projection[0])
|
val nameIndex = cursor.getColumnIndex(projection[0])
|
||||||
val numberIndex = cursor.getColumnIndex(projection[1])
|
val numberIndex = cursor.getColumnIndex(projection[1])
|
||||||
// var contactId = cursor.getInt(idx)
|
contactName = cursor.getString(nameIndex)
|
||||||
val name = cursor.getString(nameIndex)
|
|
||||||
var number = cursor.getString(numberIndex)
|
var number = cursor.getString(numberIndex)
|
||||||
number = number.replace("-", "")
|
contactPhoneNumber = number.replace("-", "")
|
||||||
BLog.LOGE("GetContact", "이름 : $name 번호 : $number ")
|
BLog.LOGE("GetContact", "이름 : $contactName 번호 : $contactPhoneNumber ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 데이터 계열은 반드시 닫아줘야 한다.
|
// 데이터 계열은 반드시 닫아줘야 한다.
|
||||||
@ -124,8 +124,8 @@ internal class ContactMenu : BottomSheetDialogFragment() {
|
|||||||
// copyToClipboard(requireContext(), packageName)
|
// copyToClipboard(requireContext(), packageName)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// appName()
|
appName()
|
||||||
// binding.detailedInfo.setOnClickListener { detailedInfo() }
|
binding.detailedInfo.setOnClickListener { detailedInfo() }
|
||||||
// binding.activityBrowser.setOnClickListener { activityBrowser() }
|
// binding.activityBrowser.setOnClickListener { activityBrowser() }
|
||||||
// binding.appStore.setOnClickListener { appStore() }
|
// binding.appStore.setOnClickListener { appStore() }
|
||||||
// binding.appFreeform.setOnClickListener { freeform() }
|
// binding.appFreeform.setOnClickListener { freeform() }
|
||||||
@ -186,66 +186,17 @@ internal class ContactMenu : BottomSheetDialogFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun appName() {
|
private fun appName() {
|
||||||
binding.appName.setOnFocusChangeListener { _, hasFocus ->
|
binding.appName.text = contactName
|
||||||
if (hasFocus) binding.appName.minWidth = resources.getDimensionPixelOffset(R.dimen.twoSeventySix)
|
binding.phoneNumber.text = contactPhoneNumber
|
||||||
else {
|
|
||||||
(requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager)
|
|
||||||
.hideSoftInputFromWindow(binding.appName.windowToken, 0)
|
|
||||||
|
|
||||||
binding.appName.apply {
|
|
||||||
minWidth = resources.getDimensionPixelOffset(R.dimen.zero)
|
|
||||||
|
|
||||||
if (text!!.isBlank()) setText(defAppName)
|
|
||||||
else setText(text!!.trim())
|
|
||||||
|
|
||||||
if (text.toString() == defAppName) appNamesPrefs?.edit()!!.remove(packageName).apply()
|
|
||||||
else appNamesPrefs?.edit()!!.putString(packageName, text.toString()).apply()
|
|
||||||
|
|
||||||
(requireParentFragment() as AppDrawer).fetchApps()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.appName.setOnKeyListener { _, keyCode, event ->
|
|
||||||
if (event.action == KeyEvent.ACTION_DOWN) {
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_BACK) {
|
|
||||||
binding.appName.clearFocus()
|
|
||||||
return@setOnKeyListener true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* detailed info dialog */
|
/* detailed info dialog */
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
private fun detailedInfo() {
|
private fun detailedInfo() {
|
||||||
val dialogBinding = AppInfoDialogBinding.inflate(lActivity!!.layoutInflater)
|
var intent = Intent(Intent.ACTION_VIEW);
|
||||||
MaterialAlertDialogBuilder(lActivity!!)
|
intent.setData(Uri.parse(ContactsContract.Contacts.CONTENT_URI.toString() + "/" + packageName));
|
||||||
.setView(dialogBinding.root)
|
startActivity(intent);
|
||||||
.setPositiveButton(android.R.string.cancel, null)
|
|
||||||
.show()
|
|
||||||
|
|
||||||
/* show app name */
|
|
||||||
dialogBinding.appName.text = packageManager.getApplicationLabel(appInfo)
|
|
||||||
|
|
||||||
/* get package info */
|
|
||||||
val packageInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
||||||
packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
|
|
||||||
} else {
|
|
||||||
packageManager.getPackageInfo(packageName, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* show infos */
|
|
||||||
dialogBinding.mixed.text =
|
|
||||||
"${resources.getString(R.string.version)}: ${packageInfo.versionName} (${PackageInfoCompat.getLongVersionCode(packageInfo).toInt()})\n" +
|
|
||||||
"${resources.getString(R.string.sdk)}: ${appInfo.minSdkVersion} ~ ${appInfo.targetSdkVersion}\n" +
|
|
||||||
"${resources.getString(R.string.uid)}: ${appInfo.uid}\n" +
|
|
||||||
"${resources.getString(R.string.first_install)}: ${dateTimeFormat(packageInfo.firstInstallTime)}\n" +
|
|
||||||
"${resources.getString(R.string.last_update)}: ${dateTimeFormat(packageInfo.lastUpdateTime)}"
|
|
||||||
|
|
||||||
/* show permissions */
|
|
||||||
dialogBinding.permissions.text = permissionsList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* activity browser dialog */
|
/* activity browser dialog */
|
||||||
|
|||||||
179
app/src/main/kotlin/rasel/lunar/launcher/apps/SearchMenu.kt
Normal file
179
app/src/main/kotlin/rasel/lunar/launcher/apps/SearchMenu.kt
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* 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.app.ActivityOptions
|
||||||
|
import android.content.ActivityNotFoundException
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.res.ColorStateList
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.icu.text.SimpleDateFormat
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.provider.ContactsContract
|
||||||
|
import android.provider.Settings
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.AdapterView
|
||||||
|
import android.widget.ArrayAdapter
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
import androidx.core.content.FileProvider
|
||||||
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import androidx.fragment.app.FragmentTransaction
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
|
import com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import rasel.lunar.launcher.BuildConfig
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
|
import rasel.lunar.launcher.R
|
||||||
|
import rasel.lunar.launcher.databinding.ActivityBrowserDialogBinding
|
||||||
|
import rasel.lunar.launcher.databinding.ContactMenuBinding
|
||||||
|
import rasel.lunar.launcher.databinding.SearchMenuBinding
|
||||||
|
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APP_NO_
|
||||||
|
import rasel.lunar.launcher.helpers.Constants.Companion.MAX_FAVORITE_APPS
|
||||||
|
import rasel.lunar.launcher.helpers.Constants.Companion.PREFS_FAVORITE_APPS
|
||||||
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenHeight
|
||||||
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.screenWidth
|
||||||
|
import rasel.lunar.launcher.utils.BLog
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
internal class SearchMenu : BottomSheetDialogFragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: SearchMenuBinding
|
||||||
|
private lateinit var searchWord: String
|
||||||
|
private lateinit var packageManager: PackageManager
|
||||||
|
private lateinit var appInfo: ApplicationInfo
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
|
binding = SearchMenuBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
/* get package name from fragment's tag */
|
||||||
|
searchWord = tag.toString()
|
||||||
|
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
(requireDialog() as BottomSheetDialog).dismissWithAnimation = true
|
||||||
|
|
||||||
|
/* copy package name */
|
||||||
|
// binding.appPackage.setOnClickListener {
|
||||||
|
// copyToClipboard(requireContext(), packageName)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
appName()
|
||||||
|
// binding.detailedInfo.setOnClickListener { detailedInfo() }
|
||||||
|
// binding.activityBrowser.setOnClickListener { activityBrowser() }
|
||||||
|
// binding.appStore.setOnClickListener { appStore() }
|
||||||
|
// binding.appFreeform.setOnClickListener { freeform() }
|
||||||
|
// binding.appInfo.setOnClickListener { appInfo() }
|
||||||
|
// binding.appShare.setOnClickListener { share() }
|
||||||
|
// binding.appUninstall.setOnClickListener { uninstall() }
|
||||||
|
binding.searchNmap.setOnClickListener {
|
||||||
|
openSearchApps("nmap://search?query=${searchWord}&appname=${BuildConfig.APPLICATION_ID}","com.nhn.android.nmap")
|
||||||
|
}
|
||||||
|
binding.searchGoogleMap.setOnClickListener {
|
||||||
|
openSearchApps("geo:0,0?q=${searchWord}","com.google.android.apps.maps")
|
||||||
|
}
|
||||||
|
binding.searchGoogle.setOnClickListener {
|
||||||
|
openSearchApps("https://www.google.com/search?q=${searchWord}","com.android.chrome")
|
||||||
|
}
|
||||||
|
binding.searchTmap.setOnClickListener {
|
||||||
|
openSearchApps("tmap://search?name=${searchWord}","com.skt.tmap.ku")
|
||||||
|
|
||||||
|
}
|
||||||
|
binding.searchNaver.setOnClickListener {
|
||||||
|
openSearchApps("https://search.naver.com/search.naver?where=nexearch&query=${searchWord}", "com.nhn.android.search")
|
||||||
|
}
|
||||||
|
binding.searchDuckduckgo.setOnClickListener {
|
||||||
|
openSearchApps("https://duckduckgo.com/?t=h_&q=${searchWord}","com.duckduckgo.mobile.android")
|
||||||
|
}
|
||||||
|
binding.searchNamuwiki.setOnClickListener {
|
||||||
|
openSearchApps("https://namu.wiki/Search?q=${searchWord}")
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.searchTranslate.setOnClickListener {
|
||||||
|
openSearchApps("https://translate.google.com/?hl=ko&sl=ko&tl=en&text=${searchWord}&op=translate","com.android.chrome")
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.searchCoupang.setOnClickListener {
|
||||||
|
openSearchApps("coupang://search?q=${searchWord}","com.coupang.mobile")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun openSearchApps(schemeString : String, pakage : String? = null) {
|
||||||
|
val gmmIntentUri = Uri.parse(schemeString)
|
||||||
|
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
|
||||||
|
pakage?.let {
|
||||||
|
mapIntent.setPackage(pakage)
|
||||||
|
}
|
||||||
|
startActivity(mapIntent)
|
||||||
|
try {
|
||||||
|
dismiss()
|
||||||
|
} catch (e : Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun appName() {
|
||||||
|
binding.keyworkd.text = searchWord
|
||||||
|
}
|
||||||
|
|
||||||
|
var mDismissCalback : DismissCalback? = null
|
||||||
|
|
||||||
|
fun show(manager: FragmentManager, tag: String? , dismissCalback : DismissCalback?) {
|
||||||
|
this.mDismissCalback = dismissCalback
|
||||||
|
this.show(manager, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun show(manager: FragmentManager, tag: String?) {
|
||||||
|
super.show(manager, tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dismiss() {
|
||||||
|
BLog.LOGE("dismiss()")
|
||||||
|
mDismissCalback?.invoke()
|
||||||
|
super.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss(dialog: DialogInterface) {
|
||||||
|
BLog.LOGE("onDismiss(dialog: DialogInterface)")
|
||||||
|
mDismissCalback?.invoke()
|
||||||
|
super.onDismiss(dialog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias DismissCalback = ()->Unit
|
||||||
@ -67,7 +67,7 @@ internal class Constants {
|
|||||||
const val KEY_LOCK_METHOD = "lock_method"
|
const val KEY_LOCK_METHOD = "lock_method"
|
||||||
|
|
||||||
/* --- */
|
/* --- */
|
||||||
const val DEFAULT_DATE_FORMAT = "EEE dx MMM, yyyy"
|
const val DEFAULT_DATE_FORMAT = "EEE, dd, MM, yyyy"
|
||||||
const val DEFAULT_ICON_SIZE = 44
|
const val DEFAULT_ICON_SIZE = 44
|
||||||
const val DEFAULT_ICON_PACK = "default_icon_pack"
|
const val DEFAULT_ICON_PACK = "default_icon_pack"
|
||||||
const val DEFAULT_GRID_COLUMNS = 4
|
const val DEFAULT_GRID_COLUMNS = 4
|
||||||
|
|||||||
@ -25,14 +25,23 @@ import android.content.IntentFilter
|
|||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.provider.AlarmClock
|
import android.provider.AlarmClock
|
||||||
|
import android.provider.CallLog
|
||||||
import android.text.format.DateFormat
|
import android.text.format.DateFormat
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.RadioButton
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
|
import androidx.core.view.get
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.MainScope
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
import rasel.lunar.launcher.R
|
import rasel.lunar.launcher.R
|
||||||
import rasel.lunar.launcher.databinding.LauncherHomeBinding
|
import rasel.lunar.launcher.databinding.LauncherHomeBinding
|
||||||
@ -51,10 +60,12 @@ import rasel.lunar.launcher.helpers.UniUtils.Companion.lockMethod
|
|||||||
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
import rasel.lunar.launcher.home.weather.WeatherExecutor
|
||||||
import rasel.lunar.launcher.qaccess.QuickAccess
|
import rasel.lunar.launcher.qaccess.QuickAccess
|
||||||
import rasel.lunar.launcher.settings.SettingsActivity
|
import rasel.lunar.launcher.settings.SettingsActivity
|
||||||
|
import rasel.lunar.launcher.todos.MissedCallsAdapter
|
||||||
import rasel.lunar.launcher.todos.TodoAdapter
|
import rasel.lunar.launcher.todos.TodoAdapter
|
||||||
import rasel.lunar.launcher.todos.TodoManager
|
import rasel.lunar.launcher.todos.TodoManager
|
||||||
import rasel.lunar.launcher.utils.BLog
|
import rasel.lunar.launcher.utils.BLog
|
||||||
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
import rasel.lunar.launcher.utils.SimpleFingerGestures
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +85,9 @@ internal class LauncherHome : Fragment() {
|
|||||||
batteryReceiver = BatteryReceiver(binding.batteryProgress)
|
batteryReceiver = BatteryReceiver(binding.batteryProgress)
|
||||||
|
|
||||||
binding.favAppsGroup.visibility = View.GONE
|
binding.favAppsGroup.visibility = View.GONE
|
||||||
|
Thread("CALLED").run {
|
||||||
|
getCallDetails()
|
||||||
|
}
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +118,8 @@ internal class LauncherHome : Fragment() {
|
|||||||
requireContext().registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
requireContext().registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||||
|
|
||||||
/* time and date */
|
/* time and date */
|
||||||
|
binding.time.textLocale = Locale.US
|
||||||
|
binding.date.textLocale = Locale.US
|
||||||
if (DateFormat.is24HourFormat(requireContext())) {
|
if (DateFormat.is24HourFormat(requireContext())) {
|
||||||
binding.time.format24Hour = timeFormat
|
binding.time.format24Hour = timeFormat
|
||||||
binding.date.format24Hour = dateFormat
|
binding.date.format24Hour = dateFormat
|
||||||
@ -120,6 +135,79 @@ internal class LauncherHome : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var callList = arrayListOf<MissedCall>()
|
||||||
|
|
||||||
|
|
||||||
|
private fun getCallDetails() {
|
||||||
|
var dateParam = Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24 * 3)).time.toString()
|
||||||
|
val managedCursor = lActivity!!.managedQuery(
|
||||||
|
CallLog.Calls.CONTENT_URI, arrayOf(
|
||||||
|
CallLog.Calls.NUMBER,
|
||||||
|
CallLog.Calls.TYPE,
|
||||||
|
CallLog.Calls.DATE,
|
||||||
|
CallLog.Calls.DURATION,
|
||||||
|
CallLog.Calls.CACHED_NAME,
|
||||||
|
), CallLog.Calls.DATE + "> ? AND " + CallLog.Calls.TYPE + " > ?", arrayOf<String>(dateParam, "2"), CallLog.Calls.DATE + " desc")
|
||||||
|
val number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER)
|
||||||
|
val type = managedCursor.getColumnIndex(CallLog.Calls.TYPE)
|
||||||
|
val date = managedCursor.getColumnIndex(CallLog.Calls.DATE)
|
||||||
|
val duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION)
|
||||||
|
val name = managedCursor.getColumnIndex(CallLog.Calls.CACHED_NAME)
|
||||||
|
var missedCalls = hashMapOf<String, MissedCall>()
|
||||||
|
if (missedCalls.size != callList.size) {
|
||||||
|
while (managedCursor.moveToNext()) {
|
||||||
|
val phNumber = managedCursor.getString(number) // mobile number
|
||||||
|
val callType = managedCursor.getString(type) // call type
|
||||||
|
val callDate = managedCursor.getString(date) // call date
|
||||||
|
val callDayTime: Date = Date(callDate.toLong())
|
||||||
|
val callDuration = managedCursor.getString(duration)
|
||||||
|
val callerName = managedCursor.getString(name)
|
||||||
|
|
||||||
|
var dir: String = ""
|
||||||
|
val dircode = callType.toInt()
|
||||||
|
when (dircode) {
|
||||||
|
CallLog.Calls.INCOMING_TYPE -> {
|
||||||
|
dir = "INCOMING_TYPE"
|
||||||
|
}
|
||||||
|
CallLog.Calls.OUTGOING_TYPE -> {
|
||||||
|
dir = "OUTGOING_TYPE"
|
||||||
|
}
|
||||||
|
CallLog.Calls.MISSED_TYPE -> {
|
||||||
|
dir = "MISSED_TYPE"
|
||||||
|
}
|
||||||
|
CallLog.Calls.VOICEMAIL_TYPE -> {
|
||||||
|
dir = "VOICEMAIL_TYPE"
|
||||||
|
}
|
||||||
|
CallLog.Calls.REJECTED_TYPE -> {
|
||||||
|
dir = "REJECTED_TYPE"
|
||||||
|
}
|
||||||
|
CallLog.Calls.BLOCKED_TYPE -> {
|
||||||
|
dir = "BLOCKED_TYPE"
|
||||||
|
}
|
||||||
|
CallLog.Calls.ANSWERED_EXTERNALLY_TYPE -> {
|
||||||
|
dir = "ANSWERED_EXTERNALLY_TYPE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var missed: MissedCall = if (missedCalls.containsKey(phNumber)) {
|
||||||
|
missedCalls.get(phNumber)!!.apply {
|
||||||
|
count = count + 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MissedCall(1,callerName,phNumber, dircode, dir, SimpleDateFormat("yyy/MM/dd-HH:mm:ss").format(callDayTime))
|
||||||
|
}
|
||||||
|
missedCalls.put(phNumber, missed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
managedCursor.close()
|
||||||
|
if (callList.size == missedCalls.size) {
|
||||||
|
} else {
|
||||||
|
callList.clear()
|
||||||
|
missedCalls.forEach { t, u ->
|
||||||
|
callList.add(u)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
/* unregister battery changes */
|
/* unregister battery changes */
|
||||||
@ -380,9 +468,19 @@ internal class LauncherHome : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* to-do list */
|
/* to-do list */
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
private fun showTodoList() {
|
private fun showTodoList() {
|
||||||
|
if (binding.missedCalls.isChecked == true) {
|
||||||
|
if (callList.size > 0) {
|
||||||
|
BLog.LOGE("callList >>> ${callList.size}")
|
||||||
|
binding.notes.adapter = MissedCallsAdapter(callList, requireContext())?.apply {
|
||||||
|
this.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
binding.notes.adapter = TodoAdapter(null, requireContext())
|
binding.notes.adapter = TodoAdapter(null, requireContext())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* get time format string */
|
/* get time format string */
|
||||||
private val timeFormat: String? get() {
|
private val timeFormat: String? get() {
|
||||||
@ -390,9 +488,9 @@ internal class LauncherHome : Fragment() {
|
|||||||
0 -> return if (DateFormat.is24HourFormat(requireContext())) {
|
0 -> return if (DateFormat.is24HourFormat(requireContext())) {
|
||||||
"kk:mm"
|
"kk:mm"
|
||||||
} else {
|
} else {
|
||||||
"h:mm a"
|
"HH:mm a"
|
||||||
}
|
}
|
||||||
1 -> return "h:mm a"
|
1 -> return "HH:mm a"
|
||||||
2 -> return "kk:mm"
|
2 -> return "kk:mm"
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@ -420,3 +518,22 @@ internal class LauncherHome : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MissedCall {
|
||||||
|
constructor(count: Int, name: String?, number: String, type: Int, typeString: String, date : String) {
|
||||||
|
this.count = count
|
||||||
|
this.name = name ?: "unknown"
|
||||||
|
this.number = number
|
||||||
|
this.type = type
|
||||||
|
this.typeString = typeString
|
||||||
|
this.date = date
|
||||||
|
}
|
||||||
|
|
||||||
|
var count : Int = 1
|
||||||
|
var name : String = "how"
|
||||||
|
var number : String = ""
|
||||||
|
var type : Int = 0
|
||||||
|
var typeString : String = ""
|
||||||
|
var date : String = ""
|
||||||
|
}
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* 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.todos
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
|
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
|
||||||
|
import rasel.lunar.launcher.R
|
||||||
|
import rasel.lunar.launcher.databinding.ListItemBinding
|
||||||
|
import rasel.lunar.launcher.databinding.TodoDialogBinding
|
||||||
|
import rasel.lunar.launcher.helpers.UniUtils.Companion.copyToClipboard
|
||||||
|
import rasel.lunar.launcher.home.MissedCall
|
||||||
|
import rasel.lunar.launcher.utils.BLog
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
|
||||||
|
internal class MissedCallsAdapter(
|
||||||
|
private val callList: ArrayList<MissedCall>,
|
||||||
|
private val context: Context) : RecyclerView.Adapter<MissedCallsAdapter.MissedCallsHolder>() {
|
||||||
|
|
||||||
|
private val currentFragment = lActivity!!.supportFragmentManager.findFragmentById(R.id.mainFragmentsContainer)
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): MissedCallsHolder {
|
||||||
|
val binding = ListItemBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
|
||||||
|
return MissedCallsHolder(binding)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
// BLog.LOGE("callList.size >>> ${callList.size}")
|
||||||
|
return callList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBindViewHolder(holder: MissedCallsHolder, position: Int) {
|
||||||
|
val todo = callList[position]
|
||||||
|
BLog.LOGE("callList >>> ${callList[position]}")
|
||||||
|
holder.view.itemText.text = "\u25CF ${if(todo.name.equals("unknown")) todo.number else { todo.name}} , ${todo.typeString} : ${todo.count} : ${todo.date}"
|
||||||
|
|
||||||
|
/* multiline texts are enabled for TodoManager */
|
||||||
|
holder.view.itemText.isSingleLine = false
|
||||||
|
/* launch edit or update dialog on item click */
|
||||||
|
holder.view.itemText.setOnClickListener { updateDialog(position) }
|
||||||
|
/* copy texts on long click */
|
||||||
|
holder.view.itemText.setOnLongClickListener {
|
||||||
|
copyToClipboard(context, todo.name)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class MissedCallsHolder(var view: ListItemBinding) : RecyclerView.ViewHolder(view.root)
|
||||||
|
|
||||||
|
/* update dialog */
|
||||||
|
private fun updateDialog(position: Int) {
|
||||||
|
val bottomSheetDialog = BottomSheetDialog(lActivity!!, R.style.BottomSheetDialog)
|
||||||
|
val dialogBinding = TodoDialogBinding.inflate(LayoutInflater.from(context))
|
||||||
|
bottomSheetDialog.setContentView(dialogBinding.root)
|
||||||
|
bottomSheetDialog.show()
|
||||||
|
bottomSheetDialog.dismissWithAnimation = true
|
||||||
|
|
||||||
|
val databaseHandler = DatabaseHandler(context)
|
||||||
|
val todo = databaseHandler.todos[position]
|
||||||
|
|
||||||
|
dialogBinding.apply {
|
||||||
|
deleteAllConfirmation.visibility = View.GONE
|
||||||
|
todoInput.setText(todo.name)
|
||||||
|
todoCancel.text = context.getString(R.string.delete)
|
||||||
|
todoCancel.setTextColor(ContextCompat.getColor(context, android.R.color.holo_red_light))
|
||||||
|
todoOk.text = context.getString(R.string.update)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete the item */
|
||||||
|
dialogBinding.todoCancel.setOnClickListener {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the item */
|
||||||
|
dialogBinding.todoOk.setOnClickListener {
|
||||||
|
val updatedTodoString = Objects.requireNonNull(dialogBinding.todoInput.text).toString().trim { it <= ' ' }
|
||||||
|
if (updatedTodoString.isNotEmpty()) {
|
||||||
|
todo.name = updatedTodoString
|
||||||
|
databaseHandler.updateTodo(todo)
|
||||||
|
bottomSheetDialog.dismiss()
|
||||||
|
} else {
|
||||||
|
dialogBinding.todoInput.error = context.getString(R.string.empty_text_field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@ import rasel.lunar.launcher.BuildConfig
|
|||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
object BLog {
|
object BLog {
|
||||||
val DEFAULT_TAG = "MyEBook_TAG"
|
val DEFAULT_TAG = "Lunatic"
|
||||||
enum class BLogType {
|
enum class BLogType {
|
||||||
D,I,E
|
D,I,E
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ class CircleImageView : androidx.appcompat.widget.AppCompatImageView {
|
|||||||
private val mShaderMatrix: Matrix = Matrix()
|
private val mShaderMatrix: Matrix = Matrix()
|
||||||
private val mBitmapPaint: Paint = Paint()
|
private val mBitmapPaint: Paint = Paint()
|
||||||
private val mBorderPaint: Paint = Paint()
|
private val mBorderPaint: Paint = Paint()
|
||||||
|
private val mLabelPaint: Paint = Paint()
|
||||||
private val mCircleBackgroundPaint: Paint = Paint()
|
private val mCircleBackgroundPaint: Paint = Paint()
|
||||||
|
|
||||||
private var mBorderColor = DEFAULT_BORDER_COLOR
|
private var mBorderColor = DEFAULT_BORDER_COLOR
|
||||||
@ -60,6 +61,7 @@ class CircleImageView : androidx.appcompat.widget.AppCompatImageView {
|
|||||||
private var mBorderOverlay = false
|
private var mBorderOverlay = false
|
||||||
private var mDisableCircularTransformation = false
|
private var mDisableCircularTransformation = false
|
||||||
|
|
||||||
|
private var label : String = ""
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) {
|
||||||
init()
|
init()
|
||||||
}
|
}
|
||||||
@ -85,6 +87,8 @@ class CircleImageView : androidx.appcompat.widget.AppCompatImageView {
|
|||||||
DEFAULT_CIRCLE_BACKGROUND_COLOR
|
DEFAULT_CIRCLE_BACKGROUND_COLOR
|
||||||
)
|
)
|
||||||
|
|
||||||
|
label = a.getString(R.styleable.CircleImageView_civ_label) ?: ""
|
||||||
|
|
||||||
a.recycle()
|
a.recycle()
|
||||||
|
|
||||||
init()
|
init()
|
||||||
@ -110,6 +114,9 @@ class CircleImageView : androidx.appcompat.widget.AppCompatImageView {
|
|||||||
mCircleBackgroundPaint.setAntiAlias(true)
|
mCircleBackgroundPaint.setAntiAlias(true)
|
||||||
mCircleBackgroundPaint.setColor(mCircleBackgroundColor)
|
mCircleBackgroundPaint.setColor(mCircleBackgroundColor)
|
||||||
|
|
||||||
|
mLabelPaint.color = Color.WHITE
|
||||||
|
mLabelPaint.isFakeBoldText = true
|
||||||
|
mLabelPaint.textAlign = Paint.Align.CENTER
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
outlineProvider = OutlineProvider()
|
outlineProvider = OutlineProvider()
|
||||||
}
|
}
|
||||||
@ -175,6 +182,10 @@ class CircleImageView : androidx.appcompat.widget.AppCompatImageView {
|
|||||||
mBorderPaint
|
mBorderPaint
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (label.length > 0) {
|
||||||
|
canvas.drawText(label.toUpperCase(),mBorderRect.centerX(),mBorderRect.height() * 0.98f, mLabelPaint)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidateDrawable(@NonNull dr: Drawable) {
|
override fun invalidateDrawable(@NonNull dr: Drawable) {
|
||||||
@ -185,6 +196,7 @@ class CircleImageView : androidx.appcompat.widget.AppCompatImageView {
|
|||||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||||
super.onSizeChanged(w, h, oldw, oldh)
|
super.onSizeChanged(w, h, oldw, oldh)
|
||||||
updateDimensions()
|
updateDimensions()
|
||||||
|
mLabelPaint.textSize = h * 0.2f
|
||||||
invalidate()
|
invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
app/src/main/res/drawable/coupang.png
Normal file
BIN
app/src/main/res/drawable/coupang.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -110,6 +110,7 @@
|
|||||||
style="@style/SearchIcons"
|
style="@style/SearchIcons"
|
||||||
android:id="@+id/search_store"/>
|
android:id="@+id/search_store"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_marginTop="10dp"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
|
|||||||
144
app/src/main/res/layout/contact_menu.xml
Normal file
144
app/src/main/res/layout/contact_menu.xml
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:padding="@dimen/twelve"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusableInTouchMode="true">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/appName"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="@dimen/zero"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="@dimen/eight"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/phoneNumber"
|
||||||
|
style="@style/Widget.Material3.Button.TextButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/appName" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/activityBrowser"
|
||||||
|
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_activity"
|
||||||
|
android:tooltipText="@string/activity_browser"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/detailedInfo"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/phoneNumber" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/detailedInfo"
|
||||||
|
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
android:layout_marginEnd="@dimen/eight"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_info"
|
||||||
|
android:tooltipText="@string/detailed_info"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/activityBrowser"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/phoneNumber" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
android:id="@+id/favGroup"
|
||||||
|
android:layout_width="@dimen/zero"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/detailedInfo"
|
||||||
|
app:singleSelection="true" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/appInfo"
|
||||||
|
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
android:layout_marginEnd="@dimen/eight"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_info2"
|
||||||
|
android:tooltipText="@string/app_info"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/appFreeform"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/appFreeform"
|
||||||
|
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
android:layout_marginEnd="@dimen/eight"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_pip"
|
||||||
|
android:tooltipText="@string/freeform"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/appStore"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/appInfo"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/appStore"
|
||||||
|
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
android:layout_marginEnd="@dimen/eight"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_store"
|
||||||
|
android:tooltipText="@string/app_store"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/appShare"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/appFreeform"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/appShare"
|
||||||
|
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
android:layout_marginEnd="@dimen/eight"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_share"
|
||||||
|
android:tooltipText="@string/share"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/appUninstall"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/appStore"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/favGroup" />
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/appUninstall"
|
||||||
|
style="@style/Widget.Material3.ExtendedFloatingActionButton.Surface"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/eight"
|
||||||
|
android:contentDescription="@null"
|
||||||
|
android:src="@drawable/ic_delete"
|
||||||
|
android:tooltipText="@string/uninstall"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/appShare"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/favGroup"
|
||||||
|
app:tint="@android:color/holo_red_light" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@ -2,6 +2,7 @@
|
|||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
@ -29,11 +30,13 @@
|
|||||||
android:textIsSelectable="false"
|
android:textIsSelectable="false"
|
||||||
android:textSize="@dimen/clockText"
|
android:textSize="@dimen/clockText"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
android:textLocale="en_US"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/batteryProgress"
|
app:layout_constraintBottom_toBottomOf="@+id/batteryProgress"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/batteryProgress"
|
app:layout_constraintEnd_toEndOf="@+id/batteryProgress"
|
||||||
app:layout_constraintStart_toStartOf="@+id/batteryProgress"
|
app:layout_constraintStart_toStartOf="@+id/batteryProgress"
|
||||||
app:layout_constraintTop_toTopOf="@+id/batteryProgress"
|
app:layout_constraintTop_toTopOf="@+id/batteryProgress"
|
||||||
app:layout_constraintVertical_bias="0.450" />
|
app:layout_constraintVertical_bias="0.450"
|
||||||
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|
||||||
<TextClock
|
<TextClock
|
||||||
android:id="@+id/date"
|
android:id="@+id/date"
|
||||||
@ -41,12 +44,14 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
|
android:textLocale="en_US"
|
||||||
android:textIsSelectable="false"
|
android:textIsSelectable="false"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/batteryProgress"
|
app:layout_constraintBottom_toBottomOf="@+id/batteryProgress"
|
||||||
app:layout_constraintEnd_toEndOf="@+id/batteryProgress"
|
app:layout_constraintEnd_toEndOf="@+id/batteryProgress"
|
||||||
app:layout_constraintStart_toStartOf="@+id/batteryProgress"
|
app:layout_constraintStart_toStartOf="@+id/batteryProgress"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/time"
|
app:layout_constraintTop_toBottomOf="@+id/time"
|
||||||
app:layout_constraintVertical_bias="0.075" />
|
app:layout_constraintVertical_bias="0.075"
|
||||||
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/weather"
|
android:id="@+id/weather"
|
||||||
@ -61,18 +66,54 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@+id/date"
|
app:layout_constraintTop_toBottomOf="@+id/date"
|
||||||
app:layout_constraintVertical_bias="0.100" />
|
app:layout_constraintVertical_bias="0.100" />
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/summaryChoose"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/batteryProgress"
|
||||||
|
>
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/missedCalls"
|
||||||
|
android:button="@null"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="전화"
|
||||||
|
android:checked="true"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<RadioButton
|
||||||
|
android:gravity="center"
|
||||||
|
android:button="@null"
|
||||||
|
android:text="투두"
|
||||||
|
android:checked="false"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
<RadioButton
|
||||||
|
android:gravity="center"
|
||||||
|
android:button="@null"
|
||||||
|
android:text="문자"
|
||||||
|
android:checked="false"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
</RadioGroup>
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/notes"
|
android:id="@+id/notes"
|
||||||
android:layout_width="@dimen/zero"
|
android:layout_width="@dimen/zero"
|
||||||
android:layout_height="@dimen/zero"
|
android:layout_height="200dp"
|
||||||
android:overScrollMode="never"
|
android:overScrollMode="never"
|
||||||
android:padding="@dimen/fortyEight"
|
android:padding="20dp"
|
||||||
android:scrollbars="none"
|
android:scrollbars="none"
|
||||||
app:layoutManager="LinearLayoutManager"
|
app:layoutManager="LinearLayoutManager"
|
||||||
app:layout_constraintBottom_toTopOf="@id/favAppsGroup"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/batteryProgress" />
|
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/summaryChoose" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.LinearLayoutCompat
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:id="@+id/favAppsGroup"
|
android:id="@+id/favAppsGroup"
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/itemText"
|
android:id="@+id/itemText"
|
||||||
android:layout_width="@dimen/zero"
|
android:layout_width="@dimen/zero"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="40dp"
|
||||||
android:padding="@dimen/twelve"
|
android:padding="@dimen/twelve"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
|||||||
89
app/src/main/res/layout/search_menu.xml
Normal file
89
app/src/main/res/layout/search_menu.xml
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:padding="@dimen/twelve"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusableInTouchMode="true">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/keyworkd"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minWidth="@dimen/zero"
|
||||||
|
android:textSize="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="@dimen/eight"
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
style="@style/SearchMenus"
|
||||||
|
android:id="@+id/quickSearch"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/keyworkd">
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
android:src="@drawable/google"
|
||||||
|
android:id="@+id/search_google"/>
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
android:src="@drawable/naver"
|
||||||
|
android:id="@+id/search_naver"/>
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
app:civ_label="DDuckGo"
|
||||||
|
android:src="@drawable/duckduckgo"
|
||||||
|
android:id="@+id/search_duckduckgo"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/quickSearch2"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/quickSearch"
|
||||||
|
style="@style/SearchMenus">
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
android:src="@drawable/namuwiki"
|
||||||
|
android:id="@+id/search_namuwiki"
|
||||||
|
style="@style/SearchMenuItem"/>
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
android:src="@drawable/gmap"
|
||||||
|
android:id="@+id/search_googleMap"/>
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
android:src="@drawable/navermap"
|
||||||
|
android:id="@+id/search_nmap"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/quickSearch3"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/quickSearch2"
|
||||||
|
style="@style/SearchMenus">
|
||||||
|
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
android:src="@drawable/coupang"
|
||||||
|
android:id="@+id/search_coupang"/>
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
android:src="@drawable/tmap"
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
android:id="@+id/search_tmap"/>
|
||||||
|
<rasel.lunar.launcher.view.CircleImageView
|
||||||
|
android:src="@drawable/translate"
|
||||||
|
style="@style/SearchMenuItem"
|
||||||
|
android:id="@+id/search_translate"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@ -5,5 +5,6 @@
|
|||||||
<attr name="civ_border_color" format="color" />
|
<attr name="civ_border_color" format="color" />
|
||||||
<attr name="civ_border_overlay" format="boolean" />
|
<attr name="civ_border_overlay" format="boolean" />
|
||||||
<attr name="civ_circle_background_color" format="color" />
|
<attr name="civ_circle_background_color" format="color" />
|
||||||
|
<attr name="civ_label" format="string" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
</resources>
|
</resources>
|
||||||
@ -37,4 +37,28 @@
|
|||||||
<item name="civ_border_color">#000000</item>
|
<item name="civ_border_color">#000000</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<style name="SearchMenuItem">
|
||||||
|
<item name="android:layout_margin">5dp</item>
|
||||||
|
<item name="android:adjustViewBounds">true</item>
|
||||||
|
<item name="android:scaleType">fitCenter</item>
|
||||||
|
<item name="android:background">@null</item>
|
||||||
|
<item name="android:layout_width">0dp</item>
|
||||||
|
<item name="android:layout_height">wrap_content</item>
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="civ_border_width">1dp</item>
|
||||||
|
<item name="civ_border_color">#000000</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<style name="SearchMenus">
|
||||||
|
<item name="layout_constraintLeft_toLeftOf">parent</item>
|
||||||
|
<item name="layout_constraintRight_toRightOf">parent</item>
|
||||||
|
<item name="android:orientation">horizontal</item>
|
||||||
|
<item name="android:background">@null</item>
|
||||||
|
<item name="android:layout_width">0dp</item>
|
||||||
|
<item name="android:layout_height">80dp</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
x
Reference in New Issue
Block a user