Feat: Added font selection to select font used throughout the launcher

Signed-off-by: HeCodes2Much <wayne6324@gmail.com>
This commit is contained in:
HeCodes2Much
2024-07-04 21:03:01 +01:00
parent 6778ed4bbe
commit e125d443bb
22 changed files with 314 additions and 12 deletions

View File

@@ -28,10 +28,4 @@ fun Fragment.showLongToast(message: String) {
fun Fragment.showShortToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
}
fun Fragment.restartApp() {
val intent = Intent(requireContext(), MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(intent)
}

View File

@@ -1,6 +1,11 @@
package com.github.droidworksstudio.launcher
import android.app.Application
import android.content.Context
import android.graphics.Typeface
import android.os.Build
import androidx.annotation.RequiresApi
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import dagger.hilt.android.HiltAndroidApp
import org.acra.ACRA
import org.acra.ReportField
@@ -8,13 +13,21 @@ import org.acra.config.dialog
import org.acra.config.mailSender
import org.acra.data.StringFormat
import org.acra.ktx.initAcra
import javax.inject.Inject
@HiltAndroidApp
class Application : Application() {
@Inject
lateinit var preferenceHelper: PreferenceHelper
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate() {
super.onCreate()
setCustomFont(applicationContext)
val pkgName = getString(R.string.app_name)
val pkgVersion = this.packageManager.getPackageInfo(
this.packageName,
@@ -64,4 +77,31 @@ class Application : Application() {
}
}
}
@RequiresApi(Build.VERSION_CODES.O)
private fun setCustomFont(context: Context) {
// Load the custom font from resources
val customFont = preferenceHelper.launcherFont.getFont(context)
// Apply the custom font to different font families
if (customFont != null) {
TypefaceUtil.setDefaultFont("DEFAULT", customFont)
TypefaceUtil.setDefaultFont("MONOSPACE", customFont)
TypefaceUtil.setDefaultFont("SERIF", customFont)
TypefaceUtil.setDefaultFont("SANS_SERIF", customFont)
}
}
}
object TypefaceUtil {
fun setDefaultFont(staticTypefaceFieldName: String, fontAssetName: Typeface) {
try {
val staticField = Typeface::class.java.getDeclaredField(staticTypefaceFieldName)
staticField.isAccessible = true
staticField.set(null, fontAssetName)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@@ -0,0 +1,48 @@
package com.github.droidworksstudio.launcher.adapter.font
import android.content.Context
import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.utils.Constants
class FontAdapter(
context: Context,
private val items: Array<Constants.Fonts>,
private val itemStrings: Array<String>
) : ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, itemStrings) {
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false)
val textView = view.findViewById<TextView>(android.R.id.text1)
textView.text = itemStrings[position]
// Set custom font based on the item
val typeface = getCustomTypefaceForItem(context, items[position])
textView.typeface = typeface
return view
}
private fun getCustomTypefaceForItem(context: Context, item: Constants.Fonts): Typeface? {
return when (item) {
Constants.Fonts.Roboto -> ResourcesCompat.getFont(context, R.font.roboto)
Constants.Fonts.OpenSans -> ResourcesCompat.getFont(context, R.font.open_sans)
Constants.Fonts.Lato -> ResourcesCompat.getFont(context, R.font.lato)
Constants.Fonts.Montserrat -> ResourcesCompat.getFont(context, R.font.montserrat)
Constants.Fonts.Merriweather -> ResourcesCompat.getFont(context, R.font.montserrat)
Constants.Fonts.DroidSans -> ResourcesCompat.getFont(context, R.font.droid_sans)
Constants.Fonts.Raleway -> ResourcesCompat.getFont(context, R.font.open_sans)
Constants.Fonts.SourceCodePro -> ResourcesCompat.getFont(context, R.font.open_sans)
Constants.Fonts.Quicksand -> ResourcesCompat.getFont(context, R.font.quicksand)
// Add other fonts as needed
else -> Typeface.DEFAULT
}
}
}

View File

@@ -0,0 +1,21 @@
package com.github.droidworksstudio.launcher.helper
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
object AppReloader {
fun restartApp(context: Context) {
val packageManager = context.packageManager
val intent = packageManager.getLaunchIntentForPackage(context.packageName)
val componentName = intent?.component
val mainIntent = Intent.makeRestartActivityTask(componentName)
// Delay the restart slightly to ensure all current activities are finished
Handler(Looper.getMainLooper()).post {
context.startActivity(mainIntent)
Runtime.getRuntime().exit(0)
}
}
}

View File

@@ -153,6 +153,21 @@ class PreferenceHelper @Inject constructor(@ApplicationContext context: Context)
}
set(value) = prefs.edit().putString(Constants.SEARCH_ENGINE, value.name).apply()
var launcherFont: Constants.Fonts
get() {
return try {
Constants.Fonts.valueOf(
prefs.getString(
Constants.LAUNCHER_FONT,
Constants.Fonts.System.name
).toString()
)
} catch (_: Exception) {
Constants.Fonts.System
}
}
set(value) = prefs.edit().putString(Constants.LAUNCHER_FONT, value.name).apply()
var swipeUpAction: Constants.Action
get() = loadAction(Constants.SWIPE_UP_ACTION, Constants.Action.ShowRecents)
set(value) = storeAction(Constants.SWIPE_UP_ACTION, value)

View File

@@ -4,19 +4,23 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.NavController
import androidx.navigation.fragment.findNavController
import com.github.droidworksstudio.common.resetDefaultLauncher
import com.github.droidworksstudio.common.restartApp
import com.github.droidworksstudio.launcher.utils.Constants
import com.github.droidworksstudio.launcher.R
import com.github.droidworksstudio.launcher.adapter.font.FontAdapter
import com.github.droidworksstudio.launcher.databinding.FragmentSettingsBinding
import com.github.droidworksstudio.launcher.helper.AppHelper
import com.github.droidworksstudio.launcher.helper.AppReloader
import com.github.droidworksstudio.launcher.helper.PreferenceHelper
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
@@ -80,6 +84,7 @@ class SettingsFragment : Fragment(),
)
binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.getString(context)
binding.miscellaneousLauncherFontsControl.text = preferenceHelper.launcherFont.getString(context)
binding.gesturesDoubleTapControl.text = preferenceHelper.doubleTapAction.getString(context)
binding.gesturesSwipeUpControl.text = preferenceHelper.swipeUpAction.getString(context)
@@ -164,7 +169,7 @@ class SettingsFragment : Fragment(),
binding.restoreView.setOnClickListener {
appHelper.restoreSharedPreferences(requireContext())
restartApp()
AppReloader.restartApp(context)
}
}
@@ -215,6 +220,10 @@ class SettingsFragment : Fragment(),
showSearchEngineDialog()
}
binding.miscellaneousLauncherFontsControl.setOnClickListener {
showLauncherFontDialog()
}
binding.gesturesDoubleTapControl.setOnClickListener {
swipeActionClickEvent(Constants.Swipe.DoubleTap)
}
@@ -251,24 +260,67 @@ class SettingsFragment : Fragment(),
}
}
private var searchEngineDialog: AlertDialog? = null
private fun showSearchEngineDialog() {
// Dismiss any existing dialog to prevent multiple dialogs open simultaneously
searchEngineDialog?.dismiss()
// Get the array of SearchEngines enum values
val items = Constants.SearchEngines.entries.toTypedArray()
// Map the enum values to their string representations
val itemStrings = items.map { it.getString(context) }.toTypedArray()
val dialog = MaterialAlertDialogBuilder(context)
val dialogBuilder = MaterialAlertDialogBuilder(context)
dialog.setTitle("Select a Search Engine")
dialog.setItems(itemStrings) { _, which ->
dialogBuilder.setTitle(getString(R.string.settings_select_search_engine))
dialogBuilder.setItems(itemStrings) { _, which ->
val selectedItem = items[which]
preferenceViewModel.setSearchEngine(selectedItem)
binding.miscellaneousSearchEngineControl.text = preferenceHelper.searchEngines.name
}
dialog.show()
// Assign the created dialog to launcherFontDialog
searchEngineDialog = dialogBuilder.create()
searchEngineDialog?.show()
}
private var launcherFontDialog: AlertDialog? = null
private fun showLauncherFontDialog() {
// Dismiss any existing dialog to prevent multiple dialogs open simultaneously
launcherFontDialog?.dismiss()
// Get the array of SearchEngines enum values
val items = Constants.Fonts.entries.toTypedArray()
// Map the enum values to their string representations
val itemStrings = items.map { it.getString(context) }.toTypedArray()
val dialogBuilder = MaterialAlertDialogBuilder(context)
dialogBuilder.setTitle(getString(R.string.settings_select_launcher_font))
dialogBuilder.setAdapter(FontAdapter(context, items, itemStrings)) { _, which ->
val selectedItem = items[which]
preferenceViewModel.setLauncherFont(selectedItem)
binding.miscellaneousLauncherFontsControl.text = preferenceHelper.launcherFont.name
// Delay the restart slightly to ensure preferences are saved
Handler(Looper.getMainLooper()).postDelayed({
AppReloader.restartApp(context)
}, 500) // Delay in milliseconds (e.g., 500ms)
}
// Assign the created dialog to launcherFontDialog
launcherFontDialog = dialogBuilder.create()
launcherFontDialog?.show()
}
// Add this function to dismiss the dialog if it's showing
private fun dismissDialogs() {
launcherFontDialog?.dismiss()
searchEngineDialog?.dismiss()
}
private fun swipeActionClickEvent(swipe: Constants.Swipe) {
// Get the array of Action enum values
val actions = Constants.Action.entries.toTypedArray()
@@ -319,4 +371,10 @@ class SettingsFragment : Fragment(),
}
dialog.show()
}
override fun onStop() {
super.onStop()
dismissDialogs()
}
}

View File

@@ -1,6 +1,8 @@
package com.github.droidworksstudio.launcher.utils
import android.content.Context
import android.graphics.Typeface
import androidx.core.content.res.ResourcesCompat
import com.github.droidworksstudio.launcher.R
object Constants {
@@ -75,6 +77,8 @@ object Constants {
const val URL_GOOGLE_PLAY_STORE = "https://play.google.com/store/search?c=apps&q"
const val APP_GOOGLE_PLAY_STORE = "market://search?c=apps&q"
const val LAUNCHER_FONT = "LAUNCHER_FONT"
const val REQUEST_INSTALL_PERMISSION = 123
const val REQUEST_LOCATION_PERMISSION_CODE = 246
@@ -158,4 +162,47 @@ object Constants {
}
}
}
enum class Fonts {
System,
Roboto,
OpenSans,
Lato,
Montserrat,
Merriweather,
DroidSans,
Raleway,
SourceCodePro,
Quicksand;
fun getFont(context: Context): Typeface? {
return when (this) {
System -> Typeface.DEFAULT
Roboto -> ResourcesCompat.getFont(context, R.font.roboto)
OpenSans -> ResourcesCompat.getFont(context, R.font.open_sans)
Lato -> ResourcesCompat.getFont(context, R.font.lato)
Montserrat -> ResourcesCompat.getFont(context, R.font.montserrat)
Merriweather -> ResourcesCompat.getFont(context, R.font.merriweather)
DroidSans -> ResourcesCompat.getFont(context, R.font.open_sans)
Raleway -> ResourcesCompat.getFont(context, R.font.raleway)
SourceCodePro -> ResourcesCompat.getFont(context, R.font.source_code_pro)
Quicksand -> ResourcesCompat.getFont(context, R.font.quicksand)
}
}
fun getString(context: Context): String {
return when (this) {
System -> context.getString(R.string.settings_font_system)
Roboto -> context.getString(R.string.settings_font_roboto)
OpenSans -> context.getString(R.string.settings_font_opensans)
Lato -> context.getString(R.string.settings_font_lato)
Montserrat -> context.getString(R.string.settings_font_montserrat)
Merriweather -> context.getString(R.string.settings_font_merriweather)
DroidSans -> context.getString(R.string.settings_font_droidsans)
Raleway -> context.getString(R.string.settings_font_raleway)
SourceCodePro -> context.getString(R.string.settings_font_sourcecodepro)
Quicksand -> context.getString(R.string.settings_font_quicksand)
}
}
}
}

View File

@@ -46,6 +46,7 @@ class PreferenceViewModel @Inject constructor(
private val batteryOrderNumberLiveData: MutableLiveData<Int> = MutableLiveData()
private val searchEngineLiveData: MutableLiveData<Constants.SearchEngines> = MutableLiveData()
private val launcherFontLiveData: MutableLiveData<Constants.Fonts> = MutableLiveData()
private val doubleTapActionLiveData: MutableLiveData<Constants.Action> = MutableLiveData()
private val swipeUpActionLiveData: MutableLiveData<Constants.Action> = MutableLiveData()
private val swipeDownActionLiveData: MutableLiveData<Constants.Action> = MutableLiveData()
@@ -236,4 +237,9 @@ class PreferenceViewModel @Inject constructor(
preferenceHelper.searchEngines = searchEngine
searchEngineLiveData.postValue((preferenceHelper.searchEngines))
}
fun setLauncherFont(launcherFont: Constants.Fonts) {
preferenceHelper.launcherFont = launcherFont
launcherFontLiveData.postValue((preferenceHelper.launcherFont))
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -566,6 +566,39 @@
tools:ignore="RtlHardcoded" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:orientation="horizontal"
tools:ignore="MissingConstraints">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/miscellaneous_launcherFonts_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left|center"
android:text="@string/settings_launcher_font"
android:textSize="@dimen/text_large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded"
style="@style/TextDefaultStyle" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/miscellaneous_launcherFonts_control"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left|center"
android:text="@string/settings_font_system"
android:textSize="@dimen/text_large"
tools:ignore="RtlHardcoded"
style="@style/TextDefaultStyle" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat

View File

@@ -2,6 +2,8 @@
<!-- Base application theme. -->
<style name="Theme.Launcher" parent="Theme.MaterialComponents.NoActionBar">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:windowDisablePreview">true</item>
<!-- Primary brand color. -->
@@ -54,14 +56,20 @@
<!-- Base application theme. -->
<style name="AppBottomSheetDialogTheme" parent="Theme.Design.BottomSheetDialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="bottomSheetStyle">@style/AppModalStyle</item>
</style>
<style name="AppModalStyle" parent="Theme.Design.BottomSheetDialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:background">@drawable/bottom_dialog_style_night</item>
</style>
<style name="CustomAlertDialog" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="shapeAppearanceOverlay">@style/RoundedCorners</item>
</style>
@@ -71,6 +79,8 @@
</style>
<style name="TextDefaultStyle" parent="@android:style/TextAppearance.Large">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:shadowColor">?attr/primaryTextShadowColor</item>
<item name="android:shadowDx">1</item>
<item name="android:shadowDy">1</item>
@@ -78,6 +88,8 @@
</style>
<style name="MaterialDialogTheme" parent="Theme.AppCompat.DayNight.Dialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
</resources>

View File

@@ -24,4 +24,14 @@
<string name="widget_weather_pressure" translatable="false">Pressure : %d hPa</string>
<string name="acra_email" translatable="false">droidworksstudio@063240.xyz</string>
<string name="settings_font_roboto" translatable="false">Roboto</string>
<string name="settings_font_opensans" translatable="false">Open Sans</string>
<string name="settings_font_lato" translatable="false">Lato</string>
<string name="settings_font_montserrat" translatable="false">Montserrat</string>
<string name="settings_font_merriweather" translatable="false">Merriweather</string>
<string name="settings_font_droidsans" translatable="false">Droid Sans</string>
<string name="settings_font_raleway" translatable="false">Raleway</string>
<string name="settings_font_sourcecodepro" translatable="false">SourceCodePro</string>
<string name="settings_font_quicksand" translatable="false">Quicksand</string>
</resources>

View File

@@ -85,8 +85,12 @@
<string name="settings_swipe_left">Swipe Left</string>
<string name="settings_swipe_right">Swipe Right</string>
<string name="settings_select_search_engine">Select a Search Engine</string>
<string name="settings_search_engine">Search Engine</string>
<string name="settings_select_launcher_font">Select a Font Family</string>
<string name="settings_launcher_font">Font Family</string>
<string name="settings_others_share">Share</string>
<string name="settings_others_feedback">Feedback</string>
<string name="settings_others_github">Github</string>
@@ -113,6 +117,8 @@
<string name="settings_units_metric">Metric</string>
<string name="settings_units_imperial">Imperial</string>
<string name="settings_font_system">System</string>
<string name="authentication_title">Authentication</string>
<string name="authentication_subtitle">Log in using your biometric credentials.</string>
<string name="authentication_cancel">Authentication Cancel</string>

View File

@@ -2,6 +2,8 @@
<!-- Base application theme. -->
<style name="Theme.Launcher" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:windowDisablePreview">true</item>
<!-- Primary brand color. -->
@@ -54,14 +56,20 @@
<!-- Base application theme. -->
<style name="AppBottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="bottomSheetStyle">@style/AppModalStyle</item>
</style>
<style name="AppModalStyle" parent="Theme.Design.Light.BottomSheetDialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:background">@drawable/bottom_dialog_style</item>
</style>
<style name="CustomAlertDialog" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="shapeAppearanceOverlay">@style/RoundedCorners</item>
</style>
@@ -71,6 +79,8 @@
</style>
<style name="TextDefaultStyle" parent="@android:style/TextAppearance.Large">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:shadowColor">?attr/primaryTextShadowColor</item>
<item name="android:shadowDx">1</item>
<item name="android:shadowDy">1</item>
@@ -78,6 +88,8 @@
</style>
<style name="MaterialDialogTheme" parent="Theme.AppCompat.DayNight.Dialog">
<item name="android:fontFamily">@android:fontFamily/system_font</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
</resources>