Move to kotlin data binding and update main fragoment

This commit is contained in:
Tommaso Berlose 2021-01-07 15:09:58 +01:00
parent ce9b343e0e
commit 98db1380b7
46 changed files with 1048 additions and 1019 deletions

Binary file not shown.

View File

@ -6,7 +6,6 @@ apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'realm-android'
@ -55,11 +54,11 @@ android {
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
}
dataBinding {
enabled = true
}
viewBinding.enabled = true
buildFeatures {
dataBinding = true
viewBinding = true
}
}
dependencies {

View File

@ -6,6 +6,7 @@ import android.graphics.Color
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.GridLayout
import android.widget.ImageView
@ -21,6 +22,8 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.card.MaterialCardView
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuHorBinding
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuListBinding
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
import com.tommasoberlose.anotherwidget.helpers.ColorHelper.isColorDark
import com.tommasoberlose.anotherwidget.utils.expand
@ -30,10 +33,6 @@ import com.tommasoberlose.anotherwidget.utils.toPixel
import com.warkiz.widget.IndicatorSeekBar
import com.warkiz.widget.OnSeekChangeListener
import com.warkiz.widget.SeekParams
import kotlinx.android.synthetic.main.bottom_sheet_menu_hor.*
import kotlinx.android.synthetic.main.bottom_sheet_menu_hor.view.*
import kotlinx.android.synthetic.main.bottom_sheet_menu_hor.view.color_loader
import kotlinx.android.synthetic.main.color_picker_menu_item.view.*
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import java.lang.Exception
@ -53,23 +52,24 @@ class BottomSheetColorPicker(
private var loadingJobs: ArrayList<Job> = ArrayList()
private lateinit var adapter: SlimAdapter
override fun show() {
val view = View.inflate(context, R.layout.bottom_sheet_menu_hor, null)
private var binding: BottomSheetMenuHorBinding = BottomSheetMenuHorBinding.inflate(LayoutInflater.from(context))
private var listBinding: BottomSheetMenuListBinding = BottomSheetMenuListBinding.inflate(LayoutInflater.from(context))
override fun show() {
window?.setDimAmount(0f)
// Header
view.header.isVisible = header != null
view.header_text.text = header ?: ""
binding.header.isVisible = header != null
binding.headerText.text = header ?: ""
// Alpha
view.alpha_selector_container.isVisible = showAlphaSelector
view.alpha_selector.setProgress(alpha.toFloat())
view.text_alpha.text = "%s: %s%%".format(context.getString(R.string.alpha), alpha)
view.alpha_selector.onSeekChangeListener = object : OnSeekChangeListener {
binding.alphaSelectorContainer.isVisible = showAlphaSelector
binding.alphaSelector.setProgress(alpha.toFloat())
binding.textAlpha.text = "%s: %s%%".format(context.getString(R.string.alpha), alpha)
binding.alphaSelector.onSeekChangeListener = object : OnSeekChangeListener {
override fun onSeeking(seekParams: SeekParams?) {
seekParams?.let {
view.text_alpha.text = "%s: %s%%".format(context.getString(R.string.alpha), it.progress)
binding.textAlpha.text = "%s: %s%%".format(context.getString(R.string.alpha), it.progress)
onAlphaChangeListener?.invoke(it.progress)
}
}
@ -84,10 +84,9 @@ class BottomSheetColorPicker(
adapter = SlimAdapter.create()
loadingJobs.add(GlobalScope.launch(Dispatchers.IO) {
val listView = View.inflate(context, R.layout.bottom_sheet_menu_list, null) as RecyclerView
listView.setHasFixedSize(true)
listBinding.root.setHasFixedSize(true)
val mLayoutManager = GridLayoutManager(context, 6)
listView.layoutManager = mLayoutManager
listBinding.root.layoutManager = mLayoutManager
adapter
.register<Int>(R.layout.color_picker_menu_item) { item, injector ->
@ -115,22 +114,22 @@ class BottomSheetColorPicker(
onColorSelected?.invoke(item)
val position = adapter.data.indexOf(item)
adapter.notifyItemChanged(position)
(listView.layoutManager as GridLayoutManager).scrollToPositionWithOffset(position,0)
(listBinding.root.layoutManager as GridLayoutManager).scrollToPositionWithOffset(position,0)
}
}
.attachTo(listView)
.attachTo(listBinding.root)
adapter.updateData(colors.toList())
withContext(Dispatchers.Main) {
view.color_loader.isVisible = false
view.list_container.addView(listView)
binding.colorLoader.isVisible = false
binding.listContainer.addView(listBinding.root)
this@BottomSheetColorPicker.behavior.state = BottomSheetBehavior.STATE_EXPANDED
view.list_container.isVisible = true
binding.listContainer.isVisible = true
}
})
setContentView(view)
setContentView(binding.root)
super.show()
}

View File

@ -1,6 +1,7 @@
package com.tommasoberlose.anotherwidget.components
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
@ -8,9 +9,8 @@ import androidx.core.view.isVisible
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.tommasoberlose.anotherwidget.R
import kotlinx.android.synthetic.main.bottom_sheet_menu.view.*
import kotlinx.android.synthetic.main.bottom_sheet_menu_item.view.*
import org.w3c.dom.Text
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuBinding
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuItemBinding
/**
* [BottomSheetDialogFragment] that uses a custom
@ -24,6 +24,8 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
private var callback: ((selectedValue: T) -> Unit)? = null
private var multipleSelectionCallback: ((selectedValues: ArrayList<T>) -> Unit)? = null
private var binding = BottomSheetMenuBinding.inflate(LayoutInflater.from(context))
fun setSelectedValue(res: T): BottomSheetMenu<T> {
selectedRes = ArrayList(listOf(res))
return this
@ -50,33 +52,31 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
}
override fun show() {
val view = View.inflate(context, R.layout.bottom_sheet_menu, null)
// Header
view.header.isVisible = header != null
view.header_text.text = header ?: ""
binding.header.isVisible = header != null
binding.headerText.text = header ?: ""
view.warning_text.isVisible = message != null
view.warning_text.text = message ?: ""
view.warning_text.setTextColor(ContextCompat.getColor(context, if (isMessageWarning) R.color.warningColorText else R.color.colorSecondaryText))
binding.warningText.isVisible = message != null
binding.warningText.text = message ?: ""
binding.warningText.setTextColor(ContextCompat.getColor(context, if (isMessageWarning) R.color.warningColorText else R.color.colorSecondaryText))
// Menu
for (item in items) {
val itemBinding = BottomSheetMenuItemBinding.inflate(LayoutInflater.from(context))
if (item.value != null) {
val itemView = View.inflate(context, R.layout.bottom_sheet_menu_item, null)
itemView.label.text = item.title
itemBinding.label.text = item.title
if (isMultiSelection) {
itemView.icon_check.isVisible = selectedRes.contains(item.value)
itemView.label.setTextColor(
itemBinding.iconCheck.isVisible = selectedRes.contains(item.value)
itemBinding.label.setTextColor(
if (selectedRes.contains(item.value)) ContextCompat.getColor(
context,
R.color.colorPrimaryText
) else ContextCompat.getColor(context, R.color.colorSecondaryText)
)
} else {
itemView.isSelected = selectedRes.contains(item.value)
itemBinding.root.isSelected = selectedRes.contains(item.value)
}
itemView.setOnClickListener {
itemBinding.root.setOnClickListener {
if (!isMultiSelection) {
callback?.invoke(item.value)
this.dismiss()
@ -88,8 +88,8 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
}
multipleSelectionCallback?.invoke(selectedRes)
itemView.icon_check.isVisible = selectedRes.contains(item.value)
itemView.label.setTextColor(
itemBinding.iconCheck.isVisible = selectedRes.contains(item.value)
itemBinding.label.setTextColor(
if (selectedRes.contains(item.value)) ContextCompat.getColor(
context,
R.color.colorPrimaryText
@ -97,17 +97,16 @@ open class BottomSheetMenu<T>(context: Context, private val header: String? = nu
)
}
item.renderCallback?.invoke(itemView.label)
item.renderCallback?.invoke(itemBinding.label)
}
view.menu.addView(itemView)
binding.menu.addView(itemBinding.root)
} else {
val itemView = View.inflate(context, R.layout.bottom_sheet_menu_divider, null)
itemView.label.text = item.title
view.menu.addView(itemView)
itemBinding.label.text = item.title
binding.menu.addView(itemBinding.root)
}
}
setContentView(view)
setContentView(binding.root)
super.show()
}

View File

@ -5,32 +5,33 @@ import android.view.View
import androidx.core.view.isVisible
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.WeatherProviderSettingsLayoutBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.utils.openURI
import kotlinx.android.synthetic.main.weather_provider_settings_layout.view.*
class BottomSheetWeatherProviderSettings(context: Context, callback: () -> Unit) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
private var binding: WeatherProviderSettingsLayoutBinding = WeatherProviderSettingsLayoutBinding.inflate(android.view.LayoutInflater.from(context))
init {
val view = View.inflate(context, R.layout.weather_provider_settings_layout, null)
view.api_key_container.isVisible = WeatherHelper.isKeyRequired()
view.action_save_key.isVisible = WeatherHelper.isKeyRequired()
binding.apiKeyContainer.isVisible = WeatherHelper.isKeyRequired()
binding.actionSaveKey.isVisible = WeatherHelper.isKeyRequired()
WeatherHelper.getProviderInfoTitle(context).let { title ->
view.info_title.text = title
view.info_title.isVisible = title != ""
binding.infoTitle.text = title
binding.infoTitle.isVisible = title != ""
}
WeatherHelper.getProviderInfoSubtitle(context).let { subtitle ->
view.info_subtitle.text = subtitle
view.info_subtitle.isVisible = subtitle != ""
binding.infoSubtitle.text = subtitle
binding.infoSubtitle.isVisible = subtitle != ""
}
view.info_provider.text = WeatherHelper.getProviderName(context)
binding.infoProvider.text = WeatherHelper.getProviderName(context)
view.api_key.editText?.setText(when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
binding.apiKey.editText?.setText(when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
Constants.WeatherProvider.OPEN_WEATHER -> Preferences.weatherProviderApiOpen
Constants.WeatherProvider.WEATHER_BIT -> Preferences.weatherProviderApiWeatherBit
Constants.WeatherProvider.WEATHER_API -> Preferences.weatherProviderApiWeatherApi
@ -41,12 +42,12 @@ class BottomSheetWeatherProviderSettings(context: Context, callback: () -> Unit)
null -> ""
})
view.action_open_provider.setOnClickListener {
binding.actionOpenProvider.setOnClickListener {
context.openURI(WeatherHelper.getProviderLink())
}
view.action_save_key.setOnClickListener {
val key = view.api_key.editText?.text.toString()
binding.actionSaveKey.setOnClickListener {
val key = binding.apiKey.editText?.text.toString()
when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
Constants.WeatherProvider.OPEN_WEATHER -> Preferences.weatherProviderApiOpen = key
Constants.WeatherProvider.WEATHER_BIT -> Preferences.weatherProviderApiWeatherBit = key
@ -59,6 +60,6 @@ class BottomSheetWeatherProviderSettings(context: Context, callback: () -> Unit)
dismiss()
}
setContentView(view)
setContentView(binding.root)
}
}

View File

@ -1,28 +1,30 @@
package com.tommasoberlose.anotherwidget.components
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import androidx.appcompat.app.AlertDialog
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.CustomNotesDialogLayoutBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import kotlinx.android.synthetic.main.custom_notes_dialog_layout.view.*
class CustomNotesDialog(context: Context, callback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
init {
val view = View.inflate(context, R.layout.custom_notes_dialog_layout, null)
view.notes.setText(Preferences.customNotes)
private var binding: CustomNotesDialogLayoutBinding = CustomNotesDialogLayoutBinding.inflate(LayoutInflater.from(context))
view.action_positive.setOnClickListener {
Preferences.customNotes = view.notes.text.toString()
init {
binding.notes.setText(Preferences.customNotes)
binding.actionPositive.setOnClickListener {
Preferences.customNotes = binding.notes.text.toString()
this.dismiss()
callback?.invoke()
}
view.notes.requestFocus()
binding.notes.requestFocus()
setContentView(view)
setContentView(binding.root)
}
}

View File

@ -7,6 +7,7 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import androidx.core.view.isVisible
import com.google.android.gms.auth.api.signin.GoogleSignIn
@ -19,6 +20,7 @@ import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.GlanceProviderSettingsLayoutBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
@ -30,17 +32,17 @@ import com.tommasoberlose.anotherwidget.ui.activities.tabs.AppNotificationsFilte
import com.tommasoberlose.anotherwidget.ui.activities.tabs.MusicPlayersFilterActivity
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import kotlinx.android.synthetic.main.glance_provider_settings_layout.view.*
import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus
class GlanceSettingsDialog(val context: Activity, val provider: Constants.GlanceProviderId, private val statusCallback: (() -> Unit)?) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
private var binding: GlanceProviderSettingsLayoutBinding = GlanceProviderSettingsLayoutBinding.inflate(LayoutInflater.from(context))
override fun show() {
val view = View.inflate(context, R.layout.glance_provider_settings_layout, null)
/* TITLE */
view.title.text = when (provider) {
binding.title.text = when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> context.getString(R.string.settings_show_music_title)
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> context.getString(R.string.settings_show_next_alarm_title)
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> context.getString(R.string.settings_low_battery_level_title)
@ -52,7 +54,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
}
/* SUBTITLE*/
view.subtitle.text = when (provider) {
binding.subtitle.text = when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> context.getString(R.string.settings_show_music_subtitle)
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> context.getString(R.string.settings_show_next_alarm_subtitle)
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> context.getString(R.string.settings_low_battery_level_subtitle)
@ -64,50 +66,50 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
}
/* SONG */
view.action_filter_music_players.isVisible = provider == Constants.GlanceProviderId.PLAYING_SONG
binding.actionFilterMusicPlayers.isVisible = provider == Constants.GlanceProviderId.PLAYING_SONG
if (provider == Constants.GlanceProviderId.PLAYING_SONG) {
view.action_filter_music_players.setOnClickListener {
binding.actionFilterMusicPlayers.setOnClickListener {
dismiss()
context.startActivityForResult(Intent(context, MusicPlayersFilterActivity::class.java), 0)
}
checkNotificationPermission(view)
checkNotificationPermission()
}
/* ALARM */
view.alarm_set_by_container.isVisible = provider == Constants.GlanceProviderId.NEXT_CLOCK_ALARM
binding.alarmSetByContainer.isVisible = provider == Constants.GlanceProviderId.NEXT_CLOCK_ALARM
if (provider == Constants.GlanceProviderId.NEXT_CLOCK_ALARM) {
view.header.text = context.getString(R.string.information_header)
view.warning_container.isVisible = false
checkNextAlarm(view)
binding.header.text = context.getString(R.string.information_header)
binding.warningContainer.isVisible = false
checkNextAlarm()
}
/* GOOGLE STEPS */
view.action_toggle_google_fit.isVisible = provider == Constants.GlanceProviderId.GOOGLE_FIT_STEPS
binding.actionToggleGoogleFit.isVisible = provider == Constants.GlanceProviderId.GOOGLE_FIT_STEPS
if (provider == Constants.GlanceProviderId.GOOGLE_FIT_STEPS) {
view.warning_container.isVisible = false
checkFitnessPermission(view)
checkGoogleFitConnection(view)
binding.warningContainer.isVisible = false
checkFitnessPermission()
checkGoogleFitConnection()
}
/* BATTERY INFO */
if (provider == Constants.GlanceProviderId.BATTERY_LEVEL_LOW) {
view.warning_container.isVisible = false
view.header.isVisible = false
view.divider.isVisible = false
binding.warningContainer.isVisible = false
binding.header.isVisible = false
binding.divider.isVisible = false
}
/* NOTIFICATIONS */
view.action_filter_notifications_app.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
view.action_change_notification_timer.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
binding.actionFilterNotificationsApp.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
binding.actionChangeNotificationTimer.isVisible = provider == Constants.GlanceProviderId.NOTIFICATIONS
if (provider == Constants.GlanceProviderId.NOTIFICATIONS) {
checkLastNotificationsPermission(view)
checkLastNotificationsPermission()
val stringArray = context.resources.getStringArray(R.array.glance_notifications_timeout)
view.action_filter_notifications_app.setOnClickListener {
binding.actionFilterNotificationsApp.setOnClickListener {
dismiss()
context.startActivityForResult(Intent(context, AppNotificationsFilterActivity::class.java), 0)
}
view.notification_timer_label.text = stringArray[Preferences.hideNotificationAfter]
view.action_change_notification_timer.setOnClickListener {
binding.notificationTimerLabel.text = stringArray[Preferences.hideNotificationAfter]
binding.actionChangeNotificationTimer.setOnClickListener {
val dialog = BottomSheetMenu<Int>(context, header = context.getString(R.string.glance_notification_hide_timeout_title)).setSelectedValue(Preferences.hideNotificationAfter)
Constants.GlanceNotificationTimer.values().forEachIndexed { index, timeout ->
dialog.addItem(stringArray[index], timeout.value)
@ -121,20 +123,20 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
/* GREETINGS */
if (provider == Constants.GlanceProviderId.GREETINGS) {
view.warning_container.isVisible = false
view.header.isVisible = false
view.divider.isVisible = false
binding.warningContainer.isVisible = false
binding.header.isVisible = false
binding.divider.isVisible = false
}
/* EVENTS */
if (provider == Constants.GlanceProviderId.EVENTS) {
view.header.isVisible = false
view.divider.isVisible = false
checkCalendarConfig(view)
binding.header.isVisible = false
binding.divider.isVisible = false
checkCalendarConfig()
}
/* TOGGLE */
view.provider_switch.setCheckedImmediatelyNoEvent(when (provider) {
binding.providerSwitch.setCheckedImmediatelyNoEvent(when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> Preferences.showMusic
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> Preferences.showNextAlarm
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> Preferences.showBatteryCharging
@ -147,7 +149,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
var job: Job? = null
view.provider_switch.setOnCheckedChangeListener { _, isChecked ->
binding.providerSwitch.setOnCheckedChangeListener { _, isChecked ->
job?.cancel()
job = GlobalScope.launch(Dispatchers.IO) {
delay(300)
@ -155,18 +157,18 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> {
Preferences.showMusic = isChecked
checkNotificationPermission(view)
checkNotificationPermission()
}
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
Preferences.showNextAlarm = isChecked
checkNextAlarm(view)
checkNextAlarm()
}
Constants.GlanceProviderId.BATTERY_LEVEL_LOW -> {
Preferences.showBatteryCharging = isChecked
}
Constants.GlanceProviderId.NOTIFICATIONS -> {
Preferences.showNotifications = isChecked
checkLastNotificationsPermission(view)
checkLastNotificationsPermission()
}
Constants.GlanceProviderId.GREETINGS -> {
Preferences.showGreetings = isChecked
@ -194,9 +196,9 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
Preferences.showDailySteps = false
}
view.warning_container.isVisible = false
checkFitnessPermission(view)
checkGoogleFitConnection(view)
binding.warningContainer.isVisible = false
checkFitnessPermission()
checkGoogleFitConnection()
}
Constants.GlanceProviderId.EVENTS -> {
Preferences.showEventsAsGlanceProvider = isChecked
@ -209,11 +211,11 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
}
}
setContentView(view)
setContentView(binding.root)
super.show()
}
private fun checkNextAlarm(view: View) {
private fun checkNextAlarm() {
with(context.getSystemService(Context.ALARM_SERVICE) as AlarmManager) {
val alarm = nextAlarmClock
if (alarm != null && alarm.showIntent != null) {
@ -223,71 +225,71 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
} catch (e: Exception) {
alarm.showIntent?.creatorPackage ?: ""
}
view.alarm_set_by_title.text = context.getString(R.string.settings_show_next_alarm_app_title).format(appNameOrPackage)
view.alarm_set_by_subtitle.text = if (AlarmHelper.isAlarmProbablyWrong(context)) context.getString(R.string.settings_show_next_alarm_app_subtitle_wrong) else context.getString(R.string.settings_show_next_alarm_app_subtitle_correct)
view.alarm_set_by_container.isVisible = true
binding.alarmSetByTitle.text = context.getString(R.string.settings_show_next_alarm_app_title).format(appNameOrPackage)
binding.alarmSetBySubtitle.text = if (AlarmHelper.isAlarmProbablyWrong(context)) context.getString(R.string.settings_show_next_alarm_app_subtitle_wrong) else context.getString(R.string.settings_show_next_alarm_app_subtitle_correct)
binding.alarmSetByContainer.isVisible = true
} else {
view.alarm_set_by_container.isVisible = false
view.header.isVisible = false
view.divider.isVisible = false
binding.alarmSetByContainer.isVisible = false
binding.header.isVisible = false
binding.divider.isVisible = false
}
}
statusCallback?.invoke()
}
private fun checkCalendarConfig(view: View) {
private fun checkCalendarConfig() {
if (!Preferences.showEvents || !context.checkGrantedPermission(Manifest.permission.READ_CALENDAR)) {
view.warning_container.isVisible = true
view.warning_title.text = context.getString(R.string.settings_show_events_as_glance_provider_error)
view.warning_container.setOnClickListener {
binding.warningContainer.isVisible = true
binding.warningTitle.text = context.getString(R.string.settings_show_events_as_glance_provider_error)
binding.warningContainer.setOnClickListener {
dismiss()
EventBus.getDefault().post(MainFragment.ChangeTabEvent(1))
}
} else {
view.warning_container.isVisible = false
binding.warningContainer.isVisible = false
}
}
private fun checkNotificationPermission(view: View) {
private fun checkNotificationPermission() {
when {
ActiveNotificationsHelper.checkNotificationAccess(context) -> {
view.warning_container.isVisible = false
binding.warningContainer.isVisible = false
MediaPlayerHelper.updatePlayingMediaInfo(context)
}
Preferences.showMusic -> {
view.warning_container.isVisible = true
view.warning_title.text = context.getString(R.string.settings_request_notification_access)
view.warning_container.setOnClickListener {
binding.warningContainer.isVisible = true
binding.warningTitle.text = context.getString(R.string.settings_request_notification_access)
binding.warningContainer.setOnClickListener {
context.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
}
}
else -> {
view.warning_container.isVisible = false
binding.warningContainer.isVisible = false
}
}
statusCallback?.invoke()
}
private fun checkLastNotificationsPermission(view: View) {
private fun checkLastNotificationsPermission() {
when {
ActiveNotificationsHelper.checkNotificationAccess(context) -> {
view.warning_container.isVisible = false
binding.warningContainer.isVisible = false
}
Preferences.showNotifications -> {
view.warning_container.isVisible = true
view.warning_title.text = context.getString(R.string.settings_request_last_notification_access)
view.warning_container.setOnClickListener {
binding.warningContainer.isVisible = true
binding.warningTitle.text = context.getString(R.string.settings_request_last_notification_access)
binding.warningContainer.setOnClickListener {
context.startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
}
}
else -> {
view.warning_container.isVisible = false
binding.warningContainer.isVisible = false
}
}
statusCallback?.invoke()
}
private fun checkFitnessPermission(view: View) {
private fun checkFitnessPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || context.checkGrantedPermission(
Manifest.permission.ACTIVITY_RECOGNITION)
) {
@ -298,10 +300,10 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
}
} else if (Preferences.showDailySteps) {
ActivityDetectionReceiver.unregisterFence(context)
view.warning_container.isVisible = true
view.warning_title.text = context.getString(R.string.settings_request_fitness_access)
view.warning_container.setOnClickListener {
requireFitnessPermission(view)
binding.warningContainer.isVisible = true
binding.warningTitle.text = context.getString(R.string.settings_request_fitness_access)
binding.warningContainer.setOnClickListener {
requireFitnessPermission()
}
} else {
ActivityDetectionReceiver.unregisterFence(context)
@ -309,36 +311,36 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
statusCallback?.invoke()
}
private fun checkGoogleFitConnection(view: View) {
private fun checkGoogleFitConnection() {
val account: GoogleSignInAccount? = GoogleSignIn.getLastSignedInAccount(context)
if (!GoogleSignIn.hasPermissions(account,
ActivityDetectionReceiver.FITNESS_OPTIONS
)) {
view.warning_container.isVisible = true
view.warning_title.text = context.getString(R.string.settings_request_fitness_access)
view.warning_container.setOnClickListener {
binding.warningContainer.isVisible = true
binding.warningTitle.text = context.getString(R.string.settings_request_fitness_access)
binding.warningContainer.setOnClickListener {
GoogleSignIn.requestPermissions(
context,
1,
account,
ActivityDetectionReceiver.FITNESS_OPTIONS)
}
view.action_connect_to_google_fit.isVisible = true
view.action_disconnect_to_google_fit.isVisible = false
view.action_connect_to_google_fit.setOnClickListener {
binding.actionConnectToGoogleFit.isVisible = true
binding.actionDisconnectToGoogleFit.isVisible = false
binding.actionConnectToGoogleFit.setOnClickListener {
GoogleSignIn.requestPermissions(
context,
1,
account,
ActivityDetectionReceiver.FITNESS_OPTIONS)
}
view.action_disconnect_to_google_fit.setOnClickListener(null)
view.google_fit_status_label.text = context.getString(R.string.google_fit_account_not_connected)
binding.actionDisconnectToGoogleFit.setOnClickListener(null)
binding.googleFitStatusLabel.text = context.getString(R.string.google_fit_account_not_connected)
} else {
view.action_connect_to_google_fit.isVisible = false
view.action_disconnect_to_google_fit.isVisible = true
view.action_connect_to_google_fit.setOnClickListener(null)
view.action_disconnect_to_google_fit.setOnClickListener {
binding.actionConnectToGoogleFit.isVisible = false
binding.actionDisconnectToGoogleFit.isVisible = true
binding.actionConnectToGoogleFit.setOnClickListener(null)
binding.actionDisconnectToGoogleFit.setOnClickListener {
GoogleSignIn.getClient(context, GoogleSignInOptions.Builder(
GoogleSignInOptions.DEFAULT_SIGN_IN).addExtension(
ActivityDetectionReceiver.FITNESS_OPTIONS
@ -346,11 +348,11 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
show()
}
}
view.google_fit_status_label.text = context.getString(R.string.google_fit_account_connected)
binding.googleFitStatusLabel.text = context.getString(R.string.google_fit_account_connected)
}
}
private fun requireFitnessPermission(view: View) {
private fun requireFitnessPermission() {
Dexter.withContext(context)
.withPermissions(
"com.google.android.gms.permission.ACTIVITY_RECOGNITION",
@ -358,7 +360,7 @@ class GlanceSettingsDialog(val context: Activity, val provider: Constants.Glance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.ACTIVITY_RECOGNITION else "com.google.android.gms.permission.ACTIVITY_RECOGNITION"
).withListener(object: MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport?) {
checkFitnessPermission(view)
checkFitnessPermission()
}
override fun onPermissionRationaleShouldBeShown(
permissions: MutableList<PermissionRequest>?,

View File

@ -1,43 +1,42 @@
package com.tommasoberlose.anotherwidget.components
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.BottomSheetMenuBinding
import com.tommasoberlose.anotherwidget.databinding.IconPackMenuItemBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import kotlinx.android.synthetic.main.bottom_sheet_menu.view.*
import kotlinx.android.synthetic.main.bottom_sheet_menu.view.header
import kotlinx.android.synthetic.main.fragment_weather_settings.*
import kotlinx.android.synthetic.main.icon_pack_menu_item.view.*
class IconPackSelector(context: Context, private val header: String? = null) : BottomSheetDialog(context, R.style.BottomSheetDialogTheme) {
private var binding = BottomSheetMenuBinding.inflate(LayoutInflater.from(context))
private var itemBinding = IconPackMenuItemBinding.inflate(LayoutInflater.from(context))
override fun show() {
val view = View.inflate(context, R.layout.bottom_sheet_menu, null)
// Header
view.header.isVisible = header != null
view.header_text.text = header ?: ""
binding.header.isVisible = header != null
binding.headerText.text = header ?: ""
view.warning_text.isVisible = false
binding.warningText.isVisible = false
// Menu
for (item in Constants.WeatherIconPack.values()) {
val itemView = View.inflate(context, R.layout.icon_pack_menu_item, null)
itemView.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.value + 1)
itemView.isSelected = item.value == Preferences.weatherIconPack
itemBinding.label.text = context.getString(R.string.settings_weather_icon_pack_default).format(item.value + 1)
itemBinding.root.isSelected = item.value == Preferences.weatherIconPack
itemView.icon_1.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01d", item.value)))
itemView.icon_2.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01n", item.value)))
itemView.icon_3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "10d", item.value)))
itemView.icon_4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "09n", item.value)))
itemBinding.icon1.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01d", item.value)))
itemBinding.icon2.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "01n", item.value)))
itemBinding.icon3.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "10d", item.value)))
itemBinding.icon4.setImageDrawable(ContextCompat.getDrawable(context, WeatherHelper.getWeatherIconResource(context, "09n", item.value)))
listOf<ImageView>(itemView.icon_1, itemView.icon_2, itemView.icon_3, itemView.icon_4).forEach {
listOf<ImageView>(itemBinding.icon1, itemBinding.icon2, itemBinding.icon3, itemBinding.icon4).forEach {
if (item == Constants.WeatherIconPack.MINIMAL) {
it.setColorFilter(ContextCompat.getColor(context, R.color.colorPrimaryText))
} else {
@ -45,13 +44,13 @@ class IconPackSelector(context: Context, private val header: String? = null) : B
}
}
itemView.setOnClickListener {
itemBinding.root.setOnClickListener {
Preferences.weatherIconPack = item.value
this.dismiss()
}
view.menu.addView(itemView)
binding.menu.addView(itemBinding.root)
}
setContentView(view)
setContentView(binding.root)
super.show()
}
}

View File

@ -1,11 +1,11 @@
package com.tommasoberlose.anotherwidget.components
import android.content.Context
import android.view.View
import android.view.LayoutInflater
import androidx.core.view.isVisible
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tommasoberlose.anotherwidget.R
import kotlinx.android.synthetic.main.bottom_sheet_dialog.view.*
import com.tommasoberlose.anotherwidget.databinding.BottomSheetDialogBinding
typealias DialogCallback = () -> Unit
@ -20,6 +20,8 @@ class MaterialBottomSheetDialog(
private var positiveCallback: DialogCallback? = null
private var negativeCallback: DialogCallback? = null
private var binding = BottomSheetDialogBinding.inflate(LayoutInflater.from(context))
fun setPositiveButton(label: String? = context.getString(android.R.string.ok), callback: DialogCallback? = null): MaterialBottomSheetDialog {
positiveButtonLabel = label
positiveCallback = callback
@ -33,30 +35,28 @@ class MaterialBottomSheetDialog(
}
override fun show() {
val view = View.inflate(context, R.layout.bottom_sheet_dialog, null)
// Header
view.title.isVisible = title != null
view.title.text = title ?: ""
binding.title.isVisible = title != null
binding.title.text = title ?: ""
view.message.isVisible = message != null
view.message.text = message ?: ""
binding.message.isVisible = message != null
binding.message.text = message ?: ""
view.action_positive.isVisible = positiveButtonLabel != null
view.action_positive.text = positiveButtonLabel ?: ""
view.action_positive.setOnClickListener {
binding.actionPositive.isVisible = positiveButtonLabel != null
binding.actionPositive.text = positiveButtonLabel ?: ""
binding.actionPositive.setOnClickListener {
positiveCallback?.invoke()
this.dismiss()
}
view.action_negative.isVisible = negativeButtonLabel != null
view.action_negative.text = negativeButtonLabel ?: ""
view.action_negative.setOnClickListener {
binding.actionNegative.isVisible = negativeButtonLabel != null
binding.actionNegative.text = negativeButtonLabel ?: ""
binding.actionNegative.setOnClickListener {
negativeCallback?.invoke()
this.dismiss()
}
setContentView(view)
setContentView(binding.root)
super.show()
}

View File

@ -16,18 +16,18 @@ import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.ActivityMainBinding
import com.tommasoberlose.anotherwidget.global.Actions
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
import com.tommasoberlose.anotherwidget.ui.activities.tabs.WeatherProviderActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private var mAppWidgetId: Int = -1
private lateinit var viewModel: MainViewModel
private lateinit var binding: ActivityMainBinding
private val mainNavController: NavController? by lazy {
Navigation.findNavController(
this,
@ -43,14 +43,16 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
binding = ActivityMainBinding.inflate(layoutInflater)
controlExtras(intent)
if (Preferences.showWallpaper) {
requirePermission()
}
setContentView(binding.root)
}
override fun onBackPressed() {
@ -86,8 +88,8 @@ class MainActivity : AppCompatActivity() {
AppWidgetManager.INVALID_APPWIDGET_ID)
if (mAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
action_add_widget.visibility = View.VISIBLE
action_add_widget.setOnClickListener {
binding.actionAddWidget.visibility = View.VISIBLE
binding.actionAddWidget.setOnClickListener {
addNewWidget()
}
}

View File

@ -8,23 +8,23 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.ActivityIntegrationsBinding
import com.tommasoberlose.anotherwidget.ui.viewmodels.IntegrationsViewModel
import kotlinx.android.synthetic.main.activity_integrations.*
import net.idik.lib.slimadapter.SlimAdapter
class IntegrationsActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: IntegrationsViewModel
private lateinit var binding: ActivityIntegrationsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(IntegrationsViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityIntegrationsBinding>(this, R.layout.activity_integrations)
binding = ActivityIntegrationsBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -33,10 +33,12 @@ class IntegrationsActivity : AppCompatActivity() {
.text(R.id.text, getString(R.string.default_name))
}
.attachTo(list_view)
.attachTo(binding.listView)
setupListener()
subscribeUi(binding, viewModel)
setContentView(binding.root)
}
private fun subscribeUi(binding: ActivityIntegrationsBinding, viewModel: IntegrationsViewModel) {
@ -45,7 +47,7 @@ class IntegrationsActivity : AppCompatActivity() {
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
}

View File

@ -15,25 +15,25 @@ import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.ActivitySupportDevBinding
import com.tommasoberlose.anotherwidget.ui.viewmodels.SupportDevViewModel
import com.tommasoberlose.anotherwidget.utils.toast
import kotlinx.android.synthetic.main.activity_support_dev.*
import net.idik.lib.slimadapter.SlimAdapter
class SupportDevActivity : AppCompatActivity(), PurchasesUpdatedListener {
private lateinit var viewModel: SupportDevViewModel
private lateinit var adapter: SlimAdapter
private lateinit var binding: ActivitySupportDevBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(SupportDevViewModel::class.java)
viewModel.billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(this).build()
DataBindingUtil.setContentView<ActivitySupportDevBinding>(this, R.layout.activity_support_dev)
binding = ActivitySupportDevBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -54,20 +54,22 @@ class SupportDevActivity : AppCompatActivity(), PurchasesUpdatedListener {
viewModel.purchase(this, item)
}
}
.attachTo(list_view)
.attachTo(binding.listView)
viewModel.openConnection()
subscribeUi(viewModel)
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
setContentView(binding.root)
}
private fun subscribeUi(viewModel: SupportDevViewModel) {
viewModel.products.observe(this, Observer {
if (it.isNotEmpty()) {
loader.isVisible = false
binding.loader.isVisible = false
}
adapter.updateData(it.sortedWith(compareBy(SkuDetails::getPriceAmountMicros)))
})

View File

@ -17,7 +17,6 @@ import com.tommasoberlose.anotherwidget.databinding.ActivityAppNotificationsFilt
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
import com.tommasoberlose.anotherwidget.ui.viewmodels.AppNotificationsViewModel
import kotlinx.android.synthetic.main.activity_app_notifications_filter.*
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
@ -26,16 +25,17 @@ class AppNotificationsFilterActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: AppNotificationsViewModel
private lateinit var binding: ActivityAppNotificationsFilterBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(AppNotificationsViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityAppNotificationsFilterBinding>(this, R.layout.activity_app_notifications_filter)
binding = ActivityAppNotificationsFilterBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -60,12 +60,14 @@ class AppNotificationsFilterActivity : AppCompatActivity() {
}
.checked(R.id.checkBox, ActiveNotificationsHelper.isAppAccepted(item.activityInfo.packageName))
}
.attachTo(list_view)
.attachTo(binding.listView)
setupListener()
subscribeUi(binding, viewModel)
search.requestFocus()
binding.search.requestFocus()
setContentView(binding.root)
}
private var filterJob: Job? = null
@ -76,22 +78,22 @@ class AppNotificationsFilterActivity : AppCompatActivity() {
viewModel.appList.observe(this, Observer {
updateList(list = it)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
})
viewModel.searchInput.observe(this, Observer { search ->
updateList(search = search)
clear_search.isVisible = search.isNotBlank()
binding.clearSearch.isVisible = search.isNotBlank()
})
viewModel.appNotificationsFilter.observe(this, {
updateList()
clear_selection.isVisible = Preferences.appNotificationsFilter != ""
binding.clearSelection.isVisible = Preferences.appNotificationsFilter != ""
})
}
private fun updateList(list: List<ResolveInfo>? = viewModel.appList.value, search: String? = viewModel.searchInput.value) {
loader.visibility = View.VISIBLE
binding.loader.visibility = View.VISIBLE
filterJob?.cancel()
filterJob = lifecycleScope.launch(Dispatchers.IO) {
if (list != null && list.isNotEmpty()) {
@ -117,22 +119,22 @@ class AppNotificationsFilterActivity : AppCompatActivity() {
withContext(Dispatchers.Main) {
adapter.updateData(filteredList)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
}
}
}
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
clear_search.setOnClickListener {
binding.clearSearch.setOnClickListener {
viewModel.searchInput.value = ""
}
clear_selection.setOnClickListener {
binding.clearSelection.setOnClickListener {
Preferences.appNotificationsFilter = ""
}
}

View File

@ -19,13 +19,6 @@ import com.bumptech.glide.Glide
import com.tommasoberlose.anotherwidget.databinding.ActivityChooseApplicationBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.ui.viewmodels.ChooseApplicationViewModel
import kotlinx.android.synthetic.main.activity_choose_application.*
import kotlinx.android.synthetic.main.activity_choose_application.action_back
import kotlinx.android.synthetic.main.activity_choose_application.clear_search
import kotlinx.android.synthetic.main.activity_choose_application.list_view
import kotlinx.android.synthetic.main.activity_choose_application.loader
import kotlinx.android.synthetic.main.activity_choose_application.search
import kotlinx.android.synthetic.main.activity_music_players_filter.*
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import net.idik.lib.slimadapter.SlimAdapterEx
@ -35,16 +28,17 @@ class ChooseApplicationActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: ChooseApplicationViewModel
private lateinit var binding: ActivityChooseApplicationBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(ChooseApplicationViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityChooseApplicationBinding>(this, R.layout.activity_choose_application)
binding = ActivityChooseApplicationBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapterEx.create()
adapter
@ -80,12 +74,14 @@ class ChooseApplicationActivity : AppCompatActivity() {
saveApp(item)
}
}
.attachTo(list_view)
.attachTo(binding.listView)
setupListener()
subscribeUi(binding, viewModel)
search.requestFocus()
binding.search.requestFocus()
setContentView(binding.root)
}
private var filterJob: Job? = null
@ -96,17 +92,17 @@ class ChooseApplicationActivity : AppCompatActivity() {
viewModel.appList.observe(this, Observer {
updateList(list = it)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
})
viewModel.searchInput.observe(this, Observer { search ->
updateList(search = search)
clear_search.isVisible = search.isNotBlank()
binding.clearSearch.isVisible = search.isNotBlank()
})
}
private fun updateList(list: List<ResolveInfo>? = viewModel.appList.value, search: String? = viewModel.searchInput.value) {
loader.visibility = View.VISIBLE
binding.loader.visibility = View.VISIBLE
filterJob?.cancel()
filterJob = lifecycleScope.launch(Dispatchers.IO) {
if (list != null && list.isNotEmpty()) {
@ -120,18 +116,18 @@ class ChooseApplicationActivity : AppCompatActivity() {
}
withContext(Dispatchers.Main) {
adapter.updateData(listOf("Default") + filteredList)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
}
}
}
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
clear_search.setOnClickListener {
binding.clearSearch.setOnClickListener {
viewModel.searchInput.value = ""
}
}

View File

@ -17,9 +17,6 @@ import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomDateViewModel
import com.tommasoberlose.anotherwidget.utils.getCapWordString
import com.tommasoberlose.anotherwidget.utils.openURI
import com.tommasoberlose.anotherwidget.utils.toast
import kotlinx.android.synthetic.main.activity_custom_date.*
import kotlinx.android.synthetic.main.activity_custom_location.action_back
import kotlinx.android.synthetic.main.activity_custom_location.list_view
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import java.lang.Exception
@ -30,17 +27,18 @@ class CustomDateActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: CustomDateViewModel
private lateinit var binding: ActivityCustomDateBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(CustomDateViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityCustomDateBinding>(this, R.layout.activity_custom_date)
binding = ActivityCustomDateBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -50,7 +48,7 @@ class CustomDateActivity : AppCompatActivity() {
.text(R.id.custom_date_example_value, SimpleDateFormat(item, Locale.getDefault()).format(
DATE.time))
}
.attachTo(list_view)
.attachTo(binding.listView)
adapter.updateData(
listOf(
@ -61,9 +59,11 @@ class CustomDateActivity : AppCompatActivity() {
setupListener()
subscribeUi(binding, viewModel)
date_format.requestFocus()
binding.dateFormat.requestFocus()
setContentView(binding.root)
}
private var formatJob: Job? = null
private fun subscribeUi(binding: ActivityCustomDateBinding, viewModel: CustomDateViewModel) {
@ -74,7 +74,7 @@ class CustomDateActivity : AppCompatActivity() {
formatJob?.cancel()
formatJob = lifecycleScope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
loader.visibility = View.VISIBLE
binding.loader.visibility = View.VISIBLE
}
delay(200)
@ -97,8 +97,8 @@ class CustomDateActivity : AppCompatActivity() {
}
withContext(Dispatchers.Main) {
loader.visibility = View.INVISIBLE
date_format_value.text = text
binding.loader.visibility = View.INVISIBLE
binding.dateFormatValue.text = text
}
}
@ -118,26 +118,26 @@ class CustomDateActivity : AppCompatActivity() {
private fun updateCapitalizeUi() {
when {
viewModel.isDateUppercase.value == true -> {
action_capitalize.setImageDrawable(ContextCompat.getDrawable(this@CustomDateActivity, R.drawable.round_publish))
action_capitalize.alpha = 1f
binding.actionCapitalize.setImageDrawable(ContextCompat.getDrawable(this@CustomDateActivity, R.drawable.round_publish))
binding.actionCapitalize.alpha = 1f
}
viewModel.isDateCapitalize.value == true -> {
action_capitalize.setImageDrawable(ContextCompat.getDrawable(this@CustomDateActivity, R.drawable.ic_capitalize))
action_capitalize.alpha = 1f
binding.actionCapitalize.setImageDrawable(ContextCompat.getDrawable(this@CustomDateActivity, R.drawable.ic_capitalize))
binding.actionCapitalize.alpha = 1f
}
else -> {
action_capitalize.setImageDrawable(ContextCompat.getDrawable(this@CustomDateActivity, R.drawable.round_publish))
action_capitalize.alpha = 0.3f
binding.actionCapitalize.setImageDrawable(ContextCompat.getDrawable(this@CustomDateActivity, R.drawable.round_publish))
binding.actionCapitalize.alpha = 0.3f
}
}
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
action_capitalize.setOnClickListener {
binding.actionCapitalize.setOnClickListener {
when {
viewModel.isDateUppercase.value == true -> {
viewModel.isDateCapitalize.value = false
@ -154,12 +154,12 @@ class CustomDateActivity : AppCompatActivity() {
}
}
action_capitalize.setOnLongClickListener {
binding.actionCapitalize.setOnLongClickListener {
toast(getString(R.string.action_capitalize_the_date))
true
}
action_date_format_info.setOnClickListener {
binding.actionDateFormatInfo.setOnClickListener {
openURI("https://developer.android.com/reference/java/text/SimpleDateFormat")
}
}

View File

@ -27,13 +27,6 @@ import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomFontViewModel
import kotlinx.android.synthetic.main.activity_choose_application.*
import kotlinx.android.synthetic.main.activity_choose_application.action_back
import kotlinx.android.synthetic.main.activity_choose_application.clear_search
import kotlinx.android.synthetic.main.activity_choose_application.list_view
import kotlinx.android.synthetic.main.activity_choose_application.loader
import kotlinx.android.synthetic.main.activity_choose_application.search
import kotlinx.android.synthetic.main.activity_music_players_filter.*
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
import net.idik.lib.slimadapter.diff.DefaultDiffCallback
@ -43,19 +36,17 @@ class CustomFontActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: CustomFontViewModel
private lateinit var binding: ActivityCustomFontBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(CustomFontViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityCustomFontBinding>(
this,
R.layout.activity_custom_font
)
binding = ActivityCustomFontBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter.enableDiff(object: DefaultDiffCallback() {
@ -145,12 +136,14 @@ class CustomFontActivity : AppCompatActivity() {
}.show()
}
}
.attachTo(list_view)
.attachTo(binding.listView)
setupListener()
subscribeUi(binding, viewModel)
search.requestFocus()
binding.search.requestFocus()
setContentView(binding.root)
}
private var filterJob: Job? = null
@ -161,12 +154,12 @@ class CustomFontActivity : AppCompatActivity() {
viewModel.fontList.observe(this, Observer {
updateList(list = it)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
})
viewModel.searchInput.observe(this, Observer { search ->
updateList(search = search)
clear_search.isVisible = search.isNotBlank()
binding.clearSearch.isVisible = search.isNotBlank()
})
}
@ -174,7 +167,7 @@ class CustomFontActivity : AppCompatActivity() {
list: ArrayList<Font>? = viewModel.fontList.value,
search: String? = viewModel.searchInput.value
) {
loader.visibility = View.VISIBLE
binding.loader.visibility = View.VISIBLE
filterJob?.cancel()
filterJob = lifecycleScope.launch(Dispatchers.IO) {
if (list != null && list.isNotEmpty()) {
@ -208,18 +201,18 @@ class CustomFontActivity : AppCompatActivity() {
}
withContext(Dispatchers.Main) {
adapter.updateData(filteredList)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
}
}
}
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
clear_search.setOnClickListener {
binding.clearSearch.setOnClickListener {
viewModel.searchInput.value = ""
}
}

View File

@ -23,12 +23,6 @@ import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.tommasoberlose.anotherwidget.databinding.ActivityCustomLocationBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.ui.viewmodels.CustomLocationViewModel
import kotlinx.android.synthetic.main.activity_custom_location.*
import kotlinx.android.synthetic.main.activity_custom_location.action_back
import kotlinx.android.synthetic.main.activity_custom_location.clear_search
import kotlinx.android.synthetic.main.activity_custom_location.list_view
import kotlinx.android.synthetic.main.activity_custom_location.loader
import kotlinx.android.synthetic.main.activity_music_players_filter.*
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
@ -36,17 +30,18 @@ class CustomLocationActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: CustomLocationViewModel
private lateinit var binding: ActivityCustomLocationBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(CustomLocationViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityCustomLocationBinding>(this, R.layout.activity_custom_location)
binding = ActivityCustomLocationBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -69,7 +64,7 @@ class CustomLocationActivity : AppCompatActivity() {
}
}
}
.attachTo(list_view)
.attachTo(binding.listView)
viewModel.addresses.observe(this, Observer {
@ -79,9 +74,11 @@ class CustomLocationActivity : AppCompatActivity() {
setupListener()
subscribeUi(binding, viewModel)
location.requestFocus()
binding.location.requestFocus()
setContentView(binding.root)
}
private var searchJob: Job? = null
private fun subscribeUi(binding: ActivityCustomLocationBinding, viewModel: CustomLocationViewModel) {
@ -90,11 +87,11 @@ class CustomLocationActivity : AppCompatActivity() {
viewModel.addresses.observe(this, Observer {
adapter.updateData(listOf("Default") + it)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
})
viewModel.locationInput.observe(this, Observer { location ->
loader.visibility = View.VISIBLE
binding.loader.visibility = View.VISIBLE
searchJob?.cancel()
searchJob = lifecycleScope.launch(Dispatchers.IO) {
delay(200)
@ -110,11 +107,11 @@ class CustomLocationActivity : AppCompatActivity() {
}
withContext(Dispatchers.Main) {
viewModel.addresses.value = list
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
}
}
clear_search.isVisible = location.isNotBlank()
binding.clearSearch.isVisible = location.isNotBlank()
})
}
@ -149,11 +146,11 @@ class CustomLocationActivity : AppCompatActivity() {
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
clear_search.setOnClickListener {
binding.clearSearch.setOnClickListener {
viewModel.locationInput.value = ""
}
}

View File

@ -17,7 +17,6 @@ import com.tommasoberlose.anotherwidget.databinding.ActivityMusicPlayersFilterBi
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.MediaPlayerHelper
import com.tommasoberlose.anotherwidget.ui.viewmodels.MusicPlayersFilterViewModel
import kotlinx.android.synthetic.main.activity_music_players_filter.*
import kotlinx.coroutines.*
import net.idik.lib.slimadapter.SlimAdapter
@ -26,16 +25,17 @@ class MusicPlayersFilterActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: MusicPlayersFilterViewModel
private lateinit var binding: ActivityMusicPlayersFilterBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(MusicPlayersFilterViewModel::class.java)
val binding = DataBindingUtil.setContentView<ActivityMusicPlayersFilterBinding>(this, R.layout.activity_music_players_filter)
binding = ActivityMusicPlayersFilterBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -60,12 +60,14 @@ class MusicPlayersFilterActivity : AppCompatActivity() {
}
.checked(R.id.checkBox, MediaPlayerHelper.isMusicPlayerAccepted(item.activityInfo.packageName))
}
.attachTo(list_view)
.attachTo(binding.listView)
setupListener()
subscribeUi(binding, viewModel)
search.requestFocus()
binding.search.requestFocus()
setContentView(binding.root)
}
private var filterJob: Job? = null
@ -76,22 +78,22 @@ class MusicPlayersFilterActivity : AppCompatActivity() {
viewModel.appList.observe(this, Observer {
updateList(list = it)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
})
viewModel.searchInput.observe(this, Observer { search ->
updateList(search = search)
clear_search.isVisible = search.isNotBlank()
binding.clearSearch.isVisible = search.isNotBlank()
})
viewModel.musicPlayersFilter.observe(this, {
updateList()
clear_selection.isVisible = Preferences.musicPlayersFilter != ""
binding.clearSelection.isVisible = Preferences.musicPlayersFilter != ""
})
}
private fun updateList(list: List<ResolveInfo>? = viewModel.appList.value, search: String? = viewModel.searchInput.value) {
loader.visibility = View.VISIBLE
binding.loader.visibility = View.VISIBLE
filterJob?.cancel()
filterJob = lifecycleScope.launch(Dispatchers.IO) {
if (list != null && list.isNotEmpty()) {
@ -117,22 +119,22 @@ class MusicPlayersFilterActivity : AppCompatActivity() {
withContext(Dispatchers.Main) {
adapter.updateData(filteredList)
loader.visibility = View.INVISIBLE
binding.loader.visibility = View.INVISIBLE
}
}
}
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
clear_search.setOnClickListener {
binding.clearSearch.setOnClickListener {
viewModel.searchInput.value = ""
}
clear_selection.setOnClickListener {
binding.clearSelection.setOnClickListener {
Preferences.musicPlayersFilter = ""
}
}

View File

@ -13,12 +13,12 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetWeatherProviderSettings
import com.tommasoberlose.anotherwidget.databinding.ActivityWeatherProviderBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import com.tommasoberlose.anotherwidget.ui.viewmodels.WeatherProviderViewModel
import kotlinx.android.synthetic.main.activity_weather_provider.*
import kotlinx.coroutines.launch
import net.idik.lib.slimadapter.SlimAdapter
import org.greenrobot.eventbus.EventBus
@ -29,16 +29,17 @@ class WeatherProviderActivity : AppCompatActivity() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: WeatherProviderViewModel
private lateinit var binding: ActivityWeatherProviderBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_weather_provider)
viewModel = ViewModelProvider(this).get(WeatherProviderViewModel::class.java)
binding = ActivityWeatherProviderBinding.inflate(layoutInflater)
list_view.setHasFixedSize(true)
binding.listView.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(this)
list_view.layoutManager = mLayoutManager
binding.listView.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -54,7 +55,7 @@ class WeatherProviderActivity : AppCompatActivity() {
Preferences.weatherProvider = provider.value
updateListItem(oldValue)
updateListItem()
loader.isVisible = true
binding.loader.isVisible = true
lifecycleScope.launch {
WeatherHelper.updateWeather(this@WeatherProviderActivity)
@ -69,7 +70,7 @@ class WeatherProviderActivity : AppCompatActivity() {
Preferences.weatherProvider = provider.value
updateListItem(oldValue)
updateListItem()
loader.isVisible = true
binding.loader.isVisible = true
lifecycleScope.launch {
WeatherHelper.updateWeather(this@WeatherProviderActivity)
@ -92,7 +93,7 @@ class WeatherProviderActivity : AppCompatActivity() {
.clicked(R.id.action_configure) {
BottomSheetWeatherProviderSettings(this) {
lifecycleScope.launch {
loader.isVisible = true
binding.loader.isVisible = true
WeatherHelper.updateWeather(this@WeatherProviderActivity)
}
}.show()
@ -110,7 +111,7 @@ class WeatherProviderActivity : AppCompatActivity() {
}
}
.image(R.id.action_configure, ContextCompat.getDrawable(this, if (WeatherHelper.isKeyRequired(provider)) R.drawable.round_settings_24 else R.drawable.outline_info_24))
}.attachTo(list_view)
}.attachTo(binding.listView)
adapter.updateData(
Constants.WeatherProvider.values().asList()
@ -120,6 +121,8 @@ class WeatherProviderActivity : AppCompatActivity() {
setupListener()
subscribeUi(viewModel)
setContentView(binding.root)
}
private fun subscribeUi(viewModel: WeatherProviderViewModel) {
@ -141,7 +144,7 @@ class WeatherProviderActivity : AppCompatActivity() {
}
private fun setupListener() {
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
onBackPressed()
}
}
@ -163,9 +166,9 @@ class WeatherProviderActivity : AppCompatActivity() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(ignore: MainFragment.UpdateUiMessageEvent?) {
loader.isVisible = Preferences.weatherProviderError == "-"
binding.loader.isVisible = Preferences.weatherProviderError == "-"
if (Preferences.weatherProviderError == "" && Preferences.weatherProviderLocationError == "") {
Snackbar.make(list_view, getString(R.string.settings_weather_provider_api_key_subtitle_all_set), Snackbar.LENGTH_LONG).show()
Snackbar.make(binding.listView, getString(R.string.settings_weather_provider_api_key_subtitle_all_set), Snackbar.LENGTH_LONG).show()
}
}
}

View File

@ -32,6 +32,7 @@ import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
import com.tommasoberlose.anotherwidget.databinding.FragmentAppMainBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.*
@ -42,8 +43,6 @@ import com.tommasoberlose.anotherwidget.ui.adapters.ViewPagerAdapter
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.*
import kotlinx.android.synthetic.main.fragment_app_main.*
import kotlinx.android.synthetic.main.the_widget_sans.*
import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
@ -57,6 +56,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: FragmentAppMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -70,7 +70,8 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
savedInstanceState: Bundle?
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
return inflater.inflate(R.layout.fragment_app_main, container, false)
binding = FragmentAppMainBinding.inflate(inflater)
return binding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
@ -78,16 +79,16 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
// Init clock
if (Preferences.showClock) {
time.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
time.setTextSize(TypedValue.COMPLEX_UNIT_SP,
binding.widgetDetail.time.setTextColor(ColorHelper.getClockFontColor(requireActivity().isDarkTheme()))
binding.widgetDetail.time.setTextSize(TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext()))
time_am_pm.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
time_am_pm.setTextSize(TypedValue.COMPLEX_UNIT_SP,
binding.widgetDetail.timeAmPm.setTextColor(ColorHelper.getClockFontColor(requireActivity().isDarkTheme()))
binding.widgetDetail.timeAmPm.setTextSize(TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2)
}
time_container.isVisible = Preferences.showClock
binding.widgetDetail.timeContainer.isVisible = Preferences.showClock
preview.layoutParams = preview.layoutParams.apply {
binding.preview.layoutParams = binding.preview.layoutParams.apply {
height = PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(requireContext()) else 0
}
subscribeUi(viewModel)
@ -111,12 +112,12 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
val navHost = childFragmentManager.findFragmentById(R.id.settings_fragment) as? NavHostFragment?
navHost?.navController?.addOnDestinationChangedListener { controller, destination, _ ->
val show = destination.id != R.id.tabSelectorFragment
action_back?.animate()?.alpha(if (show) 1f else 0f)?.setDuration(200)?.translationX((if (show) 0f else 4f).convertDpToPixel(requireContext()))?.start()
action_back?.setOnClickListener {
binding.actionBack.animate().alpha(if (show) 1f else 0f).setDuration(200).translationX((if (show) 0f else 4f).convertDpToPixel(requireContext())).start()
binding.actionBack.setOnClickListener {
controller.navigateUp()
}
action_settings?.animate()?.alpha(if (!show) 1f else 0f)?.setDuration(200)?.translationX((if (!show) 0f else -4f).convertDpToPixel(requireContext()))?.start()
fragment_title?.text = if (show) destination.label.toString() else getString(R.string.app_name)
binding.actionSettings.animate().alpha(if (!show) 1f else 0f).setDuration(200).translationX((if (!show) 0f else -4f).convertDpToPixel(requireContext())).start()
binding.fragmentTitle.text = if (show) destination.label.toString() else getString(R.string.app_name)
}
}
@ -125,76 +126,72 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
private fun updateUI() {
uiJob?.cancel()
preview?.clearAnimation()
time_container?.clearAnimation()
bottom_padding.isVisible = Preferences.showPreview
binding.preview.clearAnimation()
binding.widgetDetail.timeContainer.clearAnimation()
binding.bottomPadding.isVisible = Preferences.showPreview
if (Preferences.showPreview) {
preview?.setCardBackgroundColor(
binding.preview.setCardBackgroundColor(
ContextCompat.getColor(
requireContext(),
if (ColorHelper.getFontColor(activity?.isDarkTheme() == true)
if (ColorHelper.getFontColor(requireActivity().isDarkTheme())
.isColorDark()
) android.R.color.white else R.color.colorAccent
)
)
widget_shape_background?.setImageDrawable(
binding.widgetDetail.widgetShapeBackground.setImageDrawable(
BitmapHelper.getTintedDrawable(
requireContext(),
R.drawable.card_background,
ColorHelper.getBackgroundColor(activity?.isDarkTheme() == true)
ColorHelper.getBackgroundColor(requireActivity().isDarkTheme())
)
)
WidgetHelper.runWithCustomTypeface(requireContext()) { typeface ->
uiJob = lifecycleScope.launch(Dispatchers.IO) {
val generatedView = MainWidget.generateWidgetView(requireContext(), typeface)
val generatedView = MainWidget.generateWidgetView(requireContext(), typeface).root
withContext(Dispatchers.Main) {
generatedView.measure(0, 0)
preview?.measure(0, 0)
binding.preview.measure(0, 0)
}
val bitmap = if (preview != null) {
BitmapHelper.getBitmapFromView(
generatedView,
if (preview.width > 0) preview.width else generatedView.measuredWidth,
generatedView.measuredHeight
)
} else {
null
}
val bitmap = BitmapHelper.getBitmapFromView(
generatedView,
if (binding.preview.width > 0) binding.preview.width else generatedView.measuredWidth,
generatedView.measuredHeight
)
withContext(Dispatchers.Main) {
// Clock
time?.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
time_am_pm?.setTextColor(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))
time?.setTextSize(
binding.widgetDetail.time.setTextColor(ColorHelper.getClockFontColor(requireActivity().isDarkTheme()))
binding.widgetDetail.timeAmPm.setTextColor(ColorHelper.getClockFontColor(requireActivity().isDarkTheme()))
binding.widgetDetail.time.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext())
)
time_am_pm?.setTextSize(
binding.widgetDetail.timeAmPm.setTextSize(
TypedValue.COMPLEX_UNIT_SP,
Preferences.clockTextSize.toPixel(requireContext()) / 5 * 2
)
time_am_pm?.isVisible = Preferences.showAMPMIndicator
binding.widgetDetail.timeAmPm.isVisible = Preferences.showAMPMIndicator
// Clock bottom margin
clock_bottom_margin_none?.isVisible =
binding.widgetDetail.clockBottomMarginNone.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.NONE.value
clock_bottom_margin_small?.isVisible =
binding.widgetDetail.clockBottomMarginSmall.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.SMALL.value
clock_bottom_margin_medium?.isVisible =
binding.widgetDetail.clockBottomMarginMedium.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.MEDIUM.value
clock_bottom_margin_large?.isVisible =
binding.widgetDetail.clockBottomMarginLarge.isVisible =
Preferences.showClock && Preferences.clockBottomMargin == Constants.ClockBottomMargin.LARGE.value
if ((Preferences.showClock && (time?.alpha ?: 1f < 1f)) || (!Preferences.showClock && (time?.alpha ?: 0f > 0f))) {
if ((Preferences.showClock && (binding.widgetDetail.time.alpha ?: 1f < 1f)) || (!Preferences.showClock && (binding.widgetDetail.time.alpha ?: 0f > 0f))) {
if (Preferences.showClock) {
time_container?.layoutParams = time_container.layoutParams.apply {
binding.widgetDetail.timeContainer.layoutParams = binding.widgetDetail.timeContainer.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
}
time_container?.measure(0, 0)
binding.widgetDetail.timeContainer.measure(0, 0)
}
val initialHeight = time_container?.measuredHeight ?: 0
val initialHeight = binding.widgetDetail.timeContainer.measuredHeight ?: 0
ValueAnimator.ofFloat(
if (Preferences.showClock) 0f else 1f,
if (Preferences.showClock) 1f else 0f
@ -202,121 +199,122 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Float
time_container?.layoutParams =
time_container.layoutParams.apply {
binding.widgetDetail.timeContainer.layoutParams =
binding.widgetDetail.timeContainer.layoutParams.apply {
height = (initialHeight * animatedValue).toInt()
}
time?.alpha = animatedValue
binding.widgetDetail.time.alpha = animatedValue
}
addListener(
onStart = {
if (Preferences.showClock) {
time_container?.isVisible = true
binding.widgetDetail.timeContainer.isVisible = true
}
},
onEnd = {
if (!Preferences.showClock) {
time_container?.isVisible = false
binding.widgetDetail.timeContainer.isVisible = false
}
}
)
}.start()
if (preview != null) {
ValueAnimator.ofInt(
preview.height,
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
duration = 500L
addUpdateListener {
if (preview != null) {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}
}.start()
}
ValueAnimator.ofInt(
binding.preview.height,
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
duration = 500L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = binding.preview.layoutParams
layoutParams.height = animatedValue
binding.preview.layoutParams = layoutParams
}
}.start()
} else {
time_container?.layoutParams = time_container.layoutParams.apply {
binding.widgetDetail.timeContainer.layoutParams = binding.widgetDetail.timeContainer.layoutParams.apply {
height = RelativeLayout.LayoutParams.WRAP_CONTENT
}
time_container?.measure(0, 0)
binding.widgetDetail.timeContainer.measure(0, 0)
}
if (preview != null && preview.height == 0) {
if (binding.preview.height == 0) {
ValueAnimator.ofInt(
preview.height,
binding.preview.height,
PREVIEW_BASE_HEIGHT.toPixel(requireContext()) + if (Preferences.showClock) 100.toPixel(
requireContext()
) else 0
).apply {
duration = 300L
addUpdateListener {
if (preview != null) {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview?.layoutParams = layoutParams
}
val animatedValue = animatedValue as Int
val layoutParams = binding.preview.layoutParams
layoutParams.height = animatedValue
binding.preview.layoutParams = layoutParams
}
}.start()
}
widget_loader?.animate()?.scaleX(0f)?.scaleY(0f)?.alpha(0f)
?.setDuration(200L)?.start()
bitmap_container?.apply {
binding.widgetLoader.animate().scaleX(0f).scaleY(0f).alpha(0f)
.setDuration(200L).start()
binding.widgetDetail.bitmapContainer.apply {
setImageBitmap(bitmap)
scaleX = 0.9f
scaleY = 0.9f
}
widget?.animate()?.alpha(1f)?.start()
binding.widget.animate().alpha(1f).start()
}
}
}
} else {
if (preview != null) {
ValueAnimator.ofInt(
preview.height,
0
).apply {
duration = 300L
addUpdateListener {
if (preview != null) {
val animatedValue = animatedValue as Int
val layoutParams = preview.layoutParams
layoutParams.height = animatedValue
preview.layoutParams = layoutParams
}
}
}.start()
}
ValueAnimator.ofInt(
binding.preview.height,
0
).apply {
duration = 300L
addUpdateListener {
val animatedValue = animatedValue as Int
val layoutParams = binding.preview.layoutParams
layoutParams.height = animatedValue
binding.preview.layoutParams = layoutParams
}
}.start()
}
}
private fun subscribeUi(viewModel: MainViewModel) {
viewModel.showWallpaper.observe(viewLifecycleOwner, Observer {
activity?.let { act ->
val wallpaper = act.getCurrentWallpaper()
widget_bg.setImageDrawable(if (it) wallpaper else null)
viewModel.showWallpaper.observe(viewLifecycleOwner) {
if (it) {
val wallpaper = requireActivity().getCurrentWallpaper()
binding.widgetBg.setImageDrawable(if (it) wallpaper else null)
if (wallpaper != null) {
widget_bg.layoutParams =
(widget_bg.layoutParams as ViewGroup.MarginLayoutParams).apply {
binding.widgetBg.layoutParams =
(binding.widgetBg.layoutParams as ViewGroup.MarginLayoutParams).apply {
val metrics = DisplayMetrics()
act.windowManager.defaultDisplay.getMetrics(metrics)
val dimensions: Pair<Int, Int> = if (wallpaper.intrinsicWidth >= wallpaper.intrinsicHeight) {
metrics.heightPixels to (wallpaper.intrinsicWidth) * metrics.heightPixels / (wallpaper.intrinsicHeight)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
val display = requireActivity().display
display?.getRealMetrics(metrics)
} else {
metrics.widthPixels to (wallpaper.intrinsicHeight) * metrics.widthPixels / (wallpaper.intrinsicWidth)
@Suppress("DEPRECATION")
val display = requireActivity().windowManager.defaultDisplay
@Suppress("DEPRECATION")
display.getMetrics(metrics)
}
val dimensions: Pair<Int, Int> =
if (wallpaper.intrinsicWidth >= wallpaper.intrinsicHeight) {
metrics.heightPixels to (wallpaper.intrinsicWidth) * metrics.heightPixels / (wallpaper.intrinsicHeight)
} else {
metrics.widthPixels to (wallpaper.intrinsicHeight) * metrics.widthPixels / (wallpaper.intrinsicWidth)
}
setMargins(
if (dimensions.first >= dimensions.second) (-80).toPixel(requireContext()) else 0,
if (dimensions.first >= dimensions.second) (-80).toPixel(
requireContext()) else 0,
(-80).toPixel(requireContext()), 0, 0
)
@ -324,10 +322,12 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
height = dimensions.second
}
}
} else {
binding.widgetBg.setImageDrawable(null)
}
})
}
action_settings.setOnClickListener {
binding.actionSettings.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_appMainFragment_to_appSettingsFragment)
}
}
@ -350,7 +350,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
override fun onSharedPreferenceChanged(preferences: SharedPreferences, p1: String) {
delayJob?.cancel()
delayJob = lifecycleScope.launch(Dispatchers.IO) {
delay(200)
delay(300)
withContext(Dispatchers.Main) {
updateUI()
}
@ -365,7 +365,7 @@ class MainFragment : Fragment(), SharedPreferences.OnSharedPreferenceChangeList
fun onMessageEvent(ignore: UpdateUiMessageEvent?) {
delayJob?.cancel()
delayJob = lifecycleScope.launch(Dispatchers.IO) {
delay(200)
delay(300)
withContext(Dispatchers.Main) {
updateUI()
}

View File

@ -24,7 +24,7 @@ import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.tommasoberlose.anotherwidget.BuildConfig
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentAppSettingsBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
@ -36,7 +36,6 @@ import com.tommasoberlose.anotherwidget.ui.activities.settings.SupportDevActivit
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.openURI
import kotlinx.android.synthetic.main.fragment_settings.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -49,6 +48,7 @@ class SettingsFragment : Fragment() {
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: FragmentAppSettingsBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -63,10 +63,7 @@ class SettingsFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentSettingsBinding>(inflater,
R.layout.fragment_app_settings,
container,
false)
binding = FragmentAppSettingsBinding.inflate(inflater)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -79,16 +76,16 @@ class SettingsFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
action_back.setOnClickListener {
binding.actionBack.setOnClickListener {
Navigation.findNavController(it).popBackStack()
}
show_widget_preview_toggle.setCheckedImmediatelyNoEvent(Preferences.showPreview)
show_wallpaper_toggle.setCheckedImmediatelyNoEvent(Preferences.showWallpaper)
binding.showWidgetPreviewToggle.setCheckedImmediatelyNoEvent(Preferences.showPreview)
binding.showWallpaperToggle.setCheckedImmediatelyNoEvent(Preferences.showWallpaper)
setupListener()
app_version.text = "v%s (%s)".format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
binding.appVersion.text = "v%s (%s)".format(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
}
private fun subscribeUi(
@ -97,7 +94,7 @@ class SettingsFragment : Fragment() {
viewModel.darkThemePreference.observe(viewLifecycleOwner, Observer {
AppCompatDelegate.setDefaultNightMode(it)
maintainScrollPosition {
theme?.text = when (it) {
binding.theme?.text = when (it) {
AppCompatDelegate.MODE_NIGHT_NO -> getString(R.string.settings_subtitle_dark_theme_light)
AppCompatDelegate.MODE_NIGHT_YES -> getString(R.string.settings_subtitle_dark_theme_dark)
AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY -> getString(R.string.settings_subtitle_dark_theme_by_battery_saver)
@ -108,21 +105,21 @@ class SettingsFragment : Fragment() {
})
viewModel.installedIntegrations.observe(viewLifecycleOwner, Observer {
integrations_count_label?.text =
binding.integrationsCountLabel?.text =
getString(R.string.label_count_installed_integrations).format(
it)
})
viewModel.showPreview.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
show_widget_preview_label?.text =
binding.showWidgetPreviewLabel.text =
if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
}
})
viewModel.showWallpaper.observe(viewLifecycleOwner, Observer {
maintainScrollPosition {
show_wallpaper_label?.text =
binding.showWallpaperLabel.text =
if (it && activity?.checkGrantedPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == true) getString(
R.string.settings_visible
) else getString(R.string.settings_not_visible)
@ -131,19 +128,19 @@ class SettingsFragment : Fragment() {
}
private fun setupListener() {
action_show_widget_preview.setOnClickListener {
show_widget_preview_toggle.isChecked = !show_widget_preview_toggle.isChecked
binding.actionShowWidgetPreview.setOnClickListener {
binding.showWidgetPreviewToggle.isChecked = !binding.showWidgetPreviewToggle.isChecked
}
show_widget_preview_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.showWidgetPreviewToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.showPreview = isChecked
}
action_show_wallpaper.setOnClickListener {
show_wallpaper_toggle.isChecked = !show_wallpaper_toggle.isChecked
binding.actionShowWallpaper.setOnClickListener {
binding.showWallpaperToggle.isChecked = !binding.showWallpaperToggle.isChecked
}
show_wallpaper_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.showWallpaperToggle.setOnCheckedChangeListener { _, isChecked ->
if (isChecked) {
requirePermission()
} else {
@ -151,11 +148,11 @@ class SettingsFragment : Fragment() {
}
}
action_integrations.setOnClickListener {
binding.actionIntegrations.setOnClickListener {
startActivity(Intent(requireContext(), IntegrationsActivity::class.java))
}
action_change_theme.setOnClickListener {
binding.actionChangeTheme.setOnClickListener {
maintainScrollPosition {
BottomSheetMenu<Int>(requireContext(),
header = getString(R.string.settings_theme_title))
@ -178,30 +175,30 @@ class SettingsFragment : Fragment() {
}
}
action_translate.setOnClickListener {
binding.actionTranslate.setOnClickListener {
activity?.openURI("https://github.com/tommasoberlose/another-widget/blob/master/app/src/main/res/values/strings.xml")
}
action_website.setOnClickListener {
binding.actionWebsite.setOnClickListener {
activity?.openURI("http://tommasoberlose.com/")
}
action_feedback.setOnClickListener {
binding.actionFeedback.setOnClickListener {
activity?.openURI("https://github.com/tommasoberlose/another-widget/issues")
}
action_privacy_policy.setOnClickListener {
binding.actionPrivacyPolicy.setOnClickListener {
activity?.openURI("https://github.com/tommasoberlose/another-widget/blob/master/privacy-policy.md")
}
action_help_dev.setOnClickListener {
binding.actionHelpDev.setOnClickListener {
startActivity(Intent(requireContext(), SupportDevActivity::class.java))
}
action_refresh_widget.setOnClickListener {
action_refresh_icon
binding.actionRefreshWidget.setOnClickListener {
binding.actionRefreshIcon
.animate()
.rotation((action_refresh_icon.rotation - action_refresh_icon.rotation % 360f) + 360f)
.rotation((binding.actionRefreshIcon.rotation - binding.actionRefreshIcon.rotation % 360f) + 360f)
.withEndAction {
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
WeatherHelper.updateWeather(requireContext())
@ -215,11 +212,11 @@ class SettingsFragment : Fragment() {
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}
@ -233,7 +230,7 @@ class SettingsFragment : Fragment() {
if (report.areAllPermissionsGranted()) {
Preferences.showWallpaper = true
} else {
show_wallpaper_toggle?.isChecked = false
binding.showWallpaperToggle.isChecked = false
}
}
}

View File

@ -18,7 +18,7 @@ import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.models.CalendarSelector
import com.tommasoberlose.anotherwidget.databinding.FragmentCalendarSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentTabCalendarBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
@ -31,8 +31,6 @@ import com.tommasoberlose.anotherwidget.helpers.SettingsStringHelper
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.isDefaultSet
import com.tommasoberlose.anotherwidget.utils.toast
import kotlinx.android.synthetic.main.fragment_calendar_settings.*
import kotlinx.android.synthetic.main.fragment_calendar_settings.scrollView
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlin.Comparator
@ -44,6 +42,7 @@ class CalendarFragment : Fragment() {
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: FragmentTabCalendarBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -57,9 +56,9 @@ class CalendarFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentCalendarSettingsBinding>(inflater, R.layout.fragment_tab_calendar, container, false)
binding = FragmentTabCalendarBinding.inflate(inflater)
subscribeUi(binding, viewModel)
subscribeUi(viewModel)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -70,73 +69,72 @@ class CalendarFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
show_all_day_toggle.isChecked = Preferences.calendarAllDay
show_only_busy_events_toggle.isChecked = Preferences.showOnlyBusyEvents
show_diff_time_toggle.isChecked = Preferences.showDiffTime
show_multiple_events_toggle.isChecked = Preferences.showNextEvent
binding.showAllDayToggle.setCheckedImmediatelyNoEvent(Preferences.calendarAllDay)
binding.showOnlyBusyEventsToggle.setCheckedImmediatelyNoEvent(Preferences.showOnlyBusyEvents)
binding.showDiffTimeToggle.setCheckedImmediatelyNoEvent(Preferences.showDiffTime)
binding.showMultipleEventsToggle.setCheckedImmediatelyNoEvent(Preferences.showNextEvent)
setupListener()
scrollView?.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = scrollView?.scrollY ?: 0
binding.scrollView.viewTreeObserver.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = binding.scrollView.scrollY
}
}
private fun subscribeUi(
binding: FragmentCalendarSettingsBinding,
viewModel: MainViewModel
) {
binding.isCalendarEnabled = Preferences.showEvents
binding.isDiffEnabled = Preferences.showDiffTime || !Preferences.showEvents
viewModel.calendarAllDay.observe(viewLifecycleOwner, Observer {
viewModel.calendarAllDay.observe(viewLifecycleOwner) {
maintainScrollPosition {
all_day_label?.text =
binding.allDayLabel.text =
if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
}
})
}
viewModel.secondRowInformation.observe(viewLifecycleOwner, Observer {
viewModel.secondRowInformation.observe(viewLifecycleOwner) {
maintainScrollPosition {
second_row_info_label?.text = getString(SettingsStringHelper.getSecondRowInfoString(it))
binding.secondRowInfoLabel.text = getString(SettingsStringHelper.getSecondRowInfoString(it))
}
})
}
viewModel.showDiffTime.observe(viewLifecycleOwner, Observer {
viewModel.showDiffTime.observe(viewLifecycleOwner) {
maintainScrollPosition {
show_diff_time_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
binding.showDiffTimeLabel.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
binding.isDiffEnabled = it || !Preferences.showEvents
}
})
}
viewModel.widgetUpdateFrequency.observe(viewLifecycleOwner, Observer {
viewModel.widgetUpdateFrequency.observe(viewLifecycleOwner) {
maintainScrollPosition {
widget_update_frequency_label?.text = when (it) {
binding.widgetUpdateFrequencyLabel.text = when (it) {
Constants.WidgetUpdateFrequency.HIGH.value -> getString(R.string.settings_widget_update_frequency_high)
Constants.WidgetUpdateFrequency.DEFAULT.value -> getString(R.string.settings_widget_update_frequency_default)
Constants.WidgetUpdateFrequency.LOW.value -> getString(R.string.settings_widget_update_frequency_low)
else -> ""
}
}
})
}
viewModel.showUntil.observe(viewLifecycleOwner, Observer {
viewModel.showUntil.observe(viewLifecycleOwner) {
maintainScrollPosition {
show_until_label?.text = getString(SettingsStringHelper.getShowUntilString(it))
binding.showUntilLabel.text = getString(SettingsStringHelper.getShowUntilString(it))
}
updateCalendar()
})
}
viewModel.showNextEvent.observe(viewLifecycleOwner, Observer {
viewModel.showNextEvent.observe(viewLifecycleOwner) {
maintainScrollPosition {
show_multiple_events_label?.text =
binding.showMultipleEventsLabel.text =
if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
}
})
}
viewModel.calendarAppName.observe(viewLifecycleOwner, Observer {
viewModel.calendarAppName.observe(viewLifecycleOwner) {
maintainScrollPosition {
calendar_app_label?.text = when {
binding.calendarAppLabel.text = when {
Preferences.calendarAppName != "" -> Preferences.calendarAppName
else -> {
if (IntentHelper.getCalendarIntent(requireContext()).isDefaultSet(requireContext())) {
@ -149,19 +147,19 @@ class CalendarFragment : Fragment() {
}
}
}
})
}
viewModel.openEventDetails.observe(viewLifecycleOwner, Observer {
viewModel.openEventDetails.observe(viewLifecycleOwner) {
maintainScrollPosition {
open_event_details_label?.text = if (it) getString(R.string.default_event_app) else getString(R.string.default_calendar_app)
binding.openEventDetailsLabel.text = if (it) getString(R.string.default_event_app) else getString(R.string.default_calendar_app)
}
})
}
}
private fun setupListener() {
action_filter_calendar.setOnClickListener {
binding.actionFilterCalendar.setOnClickListener {
val calendarSelectorList: List<CalendarSelector> = CalendarHelper.getCalendarList(requireContext()).map {
CalendarSelector(
it.id,
@ -212,16 +210,16 @@ class CalendarFragment : Fragment() {
}
}
action_show_all_day.setOnClickListener {
show_all_day_toggle.isChecked = !show_all_day_toggle.isChecked
binding.actionShowAllDay.setOnClickListener {
binding.showAllDayToggle.isChecked = !binding.showAllDayToggle.isChecked
}
show_all_day_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.showAllDayToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.calendarAllDay = isChecked
updateCalendar()
}
action_change_attendee_filter.setOnClickListener {
binding.actionChangeAttendeeFilter.setOnClickListener {
val selectedValues = emptyList<Int>().toMutableList()
if (Preferences.showDeclinedEvents) {
selectedValues.add(CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED)
@ -257,32 +255,32 @@ class CalendarFragment : Fragment() {
}.show()
}
action_show_only_busy_events.setOnClickListener {
show_only_busy_events_toggle.isChecked = !show_only_busy_events_toggle.isChecked
binding.actionShowOnlyBusyEvents.setOnClickListener {
binding.showOnlyBusyEventsToggle.isChecked = !binding.showOnlyBusyEventsToggle.isChecked
}
show_only_busy_events_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.showOnlyBusyEventsToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.showOnlyBusyEvents = isChecked
updateCalendar()
}
action_show_multiple_events.setOnClickListener {
show_multiple_events_toggle.isChecked = !show_multiple_events_toggle.isChecked
binding.actionShowMultipleEvents.setOnClickListener {
binding.showMultipleEventsToggle.isChecked = !binding.showMultipleEventsToggle.isChecked
}
show_multiple_events_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.showMultipleEventsToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.showNextEvent = isChecked
}
action_show_diff_time.setOnClickListener {
show_diff_time_toggle.isChecked = !show_diff_time_toggle.isChecked
binding.actionShowDiffTime.setOnClickListener {
binding.showDiffTimeToggle.isChecked = !binding.showDiffTimeToggle.isChecked
}
show_diff_time_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.showDiffTimeToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.showDiffTime = isChecked
}
action_widget_update_frequency.setOnClickListener {
binding.actionWidgetUpdateFrequency.setOnClickListener {
if (Preferences.showEvents && Preferences.showDiffTime) {
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_widget_update_frequency_title), message = getString(R.string.settings_widget_update_frequency_subtitle)).setSelectedValue(Preferences.widgetUpdateFrequency)
.addItem(getString(R.string.settings_widget_update_frequency_high), Constants.WidgetUpdateFrequency.HIGH.value)
@ -294,7 +292,7 @@ class CalendarFragment : Fragment() {
}
}
action_second_row_info.setOnClickListener {
binding.actionSecondRowInfo.setOnClickListener {
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_second_row_info_title)).setSelectedValue(Preferences.secondRowInformation)
(0 .. 1).forEach {
dialog.addItem(getString(SettingsStringHelper.getSecondRowInfoString(it)), it)
@ -304,7 +302,7 @@ class CalendarFragment : Fragment() {
}.show()
}
action_show_until.setOnClickListener {
binding.actionShowUntil.setOnClickListener {
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_show_until_title)).setSelectedValue(Preferences.showUntil)
intArrayOf(6,7,0,1,2,3, 4, 5).forEach {
dialog.addItem(getString(SettingsStringHelper.getShowUntilString(it)), it)
@ -314,7 +312,7 @@ class CalendarFragment : Fragment() {
}.show()
}
action_open_event_details.setOnClickListener {
binding.actionOpenEventDetails.setOnClickListener {
BottomSheetMenu<Boolean>(requireContext(), header = getString(R.string.settings_event_app_title)).setSelectedValue(Preferences.openEventDetails)
.addItem(getString(R.string.default_event_app), true)
.addItem(getString(R.string.default_calendar_app), false)
@ -324,7 +322,7 @@ class CalendarFragment : Fragment() {
.show()
}
action_calendar_app.setOnClickListener {
binding.actionCalendarApp.setOnClickListener {
startActivityForResult(Intent(requireContext(), ChooseApplicationActivity::class.java), RequestCode.CALENDAR_APP_REQUEST_CODE.code)
}
}
@ -356,11 +354,11 @@ class CalendarFragment : Fragment() {
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}
}

View File

@ -7,6 +7,7 @@ import android.text.format.DateFormat
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
@ -17,7 +18,7 @@ import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentClockSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentClockBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
@ -30,8 +31,6 @@ import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import com.tommasoberlose.anotherwidget.utils.isDefaultSet
import kotlinx.android.synthetic.main.fragment_clock_settings.*
import kotlinx.android.synthetic.main.fragment_clock_settings.scrollView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -46,7 +45,7 @@ class ClockFragment : Fragment() {
private lateinit var viewModel: MainViewModel
private lateinit var colors: IntArray
private lateinit var binding: FragmentClockSettingsBinding
private lateinit var binding: FragmentClockBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -60,9 +59,9 @@ class ClockFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
binding = DataBindingUtil.inflate<FragmentClockSettingsBinding>(inflater, R.layout.fragment_clock, container, false)
binding = FragmentClockBinding.inflate(inflater)
subscribeUi(binding, viewModel)
subscribeUi(viewModel)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -73,7 +72,7 @@ class ClockFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
ampm_indicator_toggle.isChecked = Preferences.showAMPMIndicator
binding.ampmIndicatorToggle.setCheckedImmediatelyNoEvent(Preferences.showAMPMIndicator)
lifecycleScope.launch(Dispatchers.IO) {
val lazyColors = requireContext().resources.getIntArray(R.array.material_colors)
@ -83,94 +82,93 @@ class ClockFragment : Fragment() {
}
setupListener()
scrollView?.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = scrollView?.scrollY ?: 0
binding.scrollView.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = binding.scrollView.scrollY
}
}
private fun subscribeUi(
binding: FragmentClockSettingsBinding,
viewModel: MainViewModel
) {
binding.isClockVisible = Preferences.showClock
binding.is24Format = DateFormat.is24HourFormat(requireContext())
binding.isDarkModeEnabled = activity?.isDarkTheme() == true
viewModel.showBigClockWarning.observe(viewLifecycleOwner, Observer {
large_clock_warning?.isVisible = it
small_clock_warning?.isVisible = !it
})
viewModel.showBigClockWarning.observe(viewLifecycleOwner) {
binding.largeClockWarning.isVisible = it
binding.smallClockWarning.isVisible = !it
}
viewModel.clockTextSize.observe(viewLifecycleOwner, Observer {
viewModel.clockTextSize.observe(viewLifecycleOwner) {
maintainScrollPosition {
clock_text_size_label?.text = String.format("%.0fsp", it)
binding.clockTextSizeLabel.text = String.format("%.0fsp", it)
}
})
}
viewModel.showAMPMIndicator.observe(viewLifecycleOwner, Observer {
viewModel.showAMPMIndicator.observe(viewLifecycleOwner) {
maintainScrollPosition {
ampm_indicator_label?.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
binding.ampmIndicatorLabel.text = if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
}
})
}
viewModel.clockTextColor.observe(viewLifecycleOwner, Observer {
viewModel.clockTextColor.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.clockTextAlpha == "00") {
clock_text_color_label?.text = getString(R.string.transparent)
binding.clockTextColorLabel.text = getString(R.string.transparent)
} else {
clock_text_color_label?.text =
binding.clockTextColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.clockTextColorDark.observe(viewLifecycleOwner, Observer {
viewModel.clockTextColorDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.clockTextAlphaDark == "00") {
clock_text_color_label?.text = getString(R.string.transparent)
binding.clockTextColorLabel.text = getString(R.string.transparent)
} else {
clock_text_color_label?.text =
binding.clockTextColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.clockTextAlpha.observe(viewLifecycleOwner, Observer {
viewModel.clockTextAlpha.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.clockTextAlpha == "00") {
clock_text_color_label?.text = getString(R.string.transparent)
binding.clockTextColorLabel.text = getString(R.string.transparent)
} else {
clock_text_color_label?.text =
binding.clockTextColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.clockTextAlphaDark.observe(viewLifecycleOwner, Observer {
viewModel.clockTextAlphaDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.clockTextAlphaDark == "00") {
clock_text_color_label?.text = getString(R.string.transparent)
binding.clockTextColorLabel.text = getString(R.string.transparent)
} else {
clock_text_color_label?.text =
binding.clockTextColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getClockFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.clockBottomMargin.observe(viewLifecycleOwner, Observer {
viewModel.clockBottomMargin.observe(viewLifecycleOwner) {
maintainScrollPosition {
clock_bottom_margin_label?.text = when (it) {
binding.clockBottomMarginLabel.text = when (it) {
Constants.ClockBottomMargin.NONE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_none)
Constants.ClockBottomMargin.SMALL.value -> getString(R.string.settings_clock_bottom_margin_subtitle_small)
Constants.ClockBottomMargin.LARGE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_large)
else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium)
}
}
})
}
viewModel.clockAppName.observe(viewLifecycleOwner, Observer {
viewModel.clockAppName.observe(viewLifecycleOwner) {
maintainScrollPosition {
clock_app_label?.text = when {
binding.clockAppLabel.text = when {
Preferences.clockAppName != "" -> Preferences.clockAppName
else -> {
if (IntentHelper.getClockIntent(requireContext()).isDefaultSet(requireContext())) {
@ -183,15 +181,15 @@ class ClockFragment : Fragment() {
}
}
}
})
}
}
private fun setupListener() {
action_hide_large_clock_warning.setOnClickListener {
binding.actionHideLargeClockWarning.setOnClickListener {
Preferences.showBigClockWarning = false
}
action_clock_text_size.setOnClickListener {
binding.actionClockTextSize.setOnClickListener {
val dialog = BottomSheetMenu<Float>(
requireContext(),
header = getString(R.string.settings_clock_text_size_title)
@ -204,15 +202,15 @@ class ClockFragment : Fragment() {
}.show()
}
action_ampm_indicator_size.setOnClickListener {
ampm_indicator_toggle.isChecked = !ampm_indicator_toggle.isChecked
binding.actionAmpmIndicatorSize.setOnClickListener {
binding.ampmIndicatorToggle.isChecked = !binding.ampmIndicatorToggle.isChecked
}
ampm_indicator_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.ampmIndicatorToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.showAMPMIndicator = isChecked
}
action_clock_text_color.setOnClickListener {
binding.actionClockTextColor.setOnClickListener {
BottomSheetColorPicker(requireContext(),
colors = colors,
header = getString(R.string.settings_font_color_title),
@ -239,7 +237,7 @@ class ClockFragment : Fragment() {
).show()
}
action_clock_bottom_margin_size.setOnClickListener {
binding.actionClockBottomMarginSize.setOnClickListener {
BottomSheetMenu<Int>(
requireContext(),
header = getString(R.string.settings_clock_bottom_margin_title)
@ -265,7 +263,7 @@ class ClockFragment : Fragment() {
}.show()
}
action_clock_app.setOnClickListener {
binding.actionClockApp.setOnClickListener {
startActivityForResult(
Intent(requireContext(), ChooseApplicationActivity::class.java),
RequestCode.CLOCK_APP_REQUEST_CODE.code
@ -289,11 +287,11 @@ class ClockFragment : Fragment() {
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}
}

View File

@ -31,7 +31,7 @@ import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.CustomNotesDialog
import com.tommasoberlose.anotherwidget.components.GlanceSettingsDialog
import com.tommasoberlose.anotherwidget.databinding.FragmentGlanceSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentTabGlanceBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.ActiveNotificationsHelper
@ -45,10 +45,6 @@ import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.convertDpToPixel
import kotlinx.android.synthetic.main.fragment_calendar_settings.*
import kotlinx.android.synthetic.main.fragment_glance_settings.*
import kotlinx.android.synthetic.main.fragment_glance_settings.scrollView
import kotlinx.android.synthetic.main.fragment_tab_selector.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.idik.lib.slimadapter.SlimAdapter
@ -64,6 +60,7 @@ class GlanceTabFragment : Fragment() {
private lateinit var adapter: SlimAdapter
private lateinit var viewModel: MainViewModel
private lateinit var list: ArrayList<Constants.GlanceProviderId>
private lateinit var binding: FragmentTabGlanceBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -77,12 +74,9 @@ class GlanceTabFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentGlanceSettingsBinding>(inflater,
R.layout.fragment_tab_glance,
container,
false)
binding = FragmentTabGlanceBinding.inflate(inflater)
subscribeUi(binding, viewModel)
subscribeUi(viewModel)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -96,9 +90,9 @@ class GlanceTabFragment : Fragment() {
super.onActivityCreated(savedInstanceState)
// List
providers_list.setHasFixedSize(true)
binding.providersList.setHasFixedSize(true)
val mLayoutManager = LinearLayoutManager(context)
providers_list.layoutManager = mLayoutManager
binding.providersList.layoutManager = mLayoutManager
adapter = SlimAdapter.create()
adapter
@ -257,7 +251,7 @@ class GlanceTabFragment : Fragment() {
injector.alpha(R.id.label, if (isVisible) 1f else .25f)
injector.alpha(R.id.icon, if (isVisible) 1f else .25f)
}
.attachTo(providers_list)
.attachTo(binding.providersList)
val mIth = ItemTouchHelper(
object : ItemTouchHelper.SimpleCallback(
@ -348,19 +342,18 @@ class GlanceTabFragment : Fragment() {
}
})
mIth.attachToRecyclerView(providers_list)
mIth.attachToRecyclerView(binding.providersList)
adapter.updateData(list.mapNotNull { GlanceProviderHelper.getGlanceProviderById(requireContext(), it) })
providers_list.isNestedScrollingEnabled = false
binding.providersList.isNestedScrollingEnabled = false
setupListener()
scrollView?.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = scrollView?.scrollY ?: 0
binding.scrollView.viewTreeObserver.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = binding.scrollView.scrollY
}
}
private fun subscribeUi(
binding: FragmentGlanceSettingsBinding,
viewModel: MainViewModel,
) {
binding.isGlanceVisible = Preferences.showGlance
@ -432,11 +425,11 @@ class GlanceTabFragment : Fragment() {
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}

View File

@ -16,7 +16,7 @@ import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentGeneralSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentTabLayoutBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.ColorHelper
@ -27,10 +27,6 @@ import com.tommasoberlose.anotherwidget.ui.activities.tabs.CustomDateActivity
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import kotlinx.android.synthetic.main.fragment_calendar_settings.*
import kotlinx.android.synthetic.main.fragment_clock_settings.*
import kotlinx.android.synthetic.main.fragment_general_settings.*
import kotlinx.android.synthetic.main.fragment_tab_selector.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -46,6 +42,7 @@ class LayoutFragment : Fragment() {
private lateinit var viewModel: MainViewModel
private lateinit var colors: IntArray
private lateinit var binding: FragmentTabLayoutBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -59,7 +56,7 @@ class LayoutFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentGeneralSettingsBinding>(inflater, R.layout.fragment_tab_layout, container, false)
binding = FragmentTabLayoutBinding.inflate(inflater)
subscribeUi(viewModel)
@ -73,7 +70,7 @@ class LayoutFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
show_dividers_toggle.isChecked = Preferences.showDividers
binding.showDividersToggle.setCheckedImmediatelyNoEvent(Preferences.showDividers)
setupListener()
lifecycleScope.launch(Dispatchers.IO) {
@ -83,8 +80,8 @@ class LayoutFragment : Fragment() {
}
}
scrollView?.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = scrollView?.scrollY ?: 0
binding.scrollView.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = binding.scrollView.scrollY
}
}
@ -94,78 +91,78 @@ class LayoutFragment : Fragment() {
viewModel: MainViewModel
) {
viewModel.secondRowTopMargin.observe(viewLifecycleOwner, Observer {
viewModel.secondRowTopMargin.observe(viewLifecycleOwner) {
maintainScrollPosition {
second_row_top_margin_label?.text = when (it) {
binding.secondRowTopMarginLabel.text = when (it) {
Constants.SecondRowTopMargin.NONE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_none)
Constants.SecondRowTopMargin.SMALL.value -> getString(R.string.settings_clock_bottom_margin_subtitle_small)
Constants.SecondRowTopMargin.LARGE.value -> getString(R.string.settings_clock_bottom_margin_subtitle_large)
else -> getString(R.string.settings_clock_bottom_margin_subtitle_medium)
}
}
})
}
viewModel.backgroundCardColor.observe(viewLifecycleOwner, Observer {
viewModel.backgroundCardColor.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.backgroundCardAlpha == "00") {
background_color_label?.text = getString(R.string.transparent)
binding.backgroundColorLabel.text = getString(R.string.transparent)
} else {
background_color_label?.text =
binding.backgroundColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getBackgroundColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.backgroundCardColorDark.observe(viewLifecycleOwner, Observer {
viewModel.backgroundCardColorDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.backgroundCardAlphaDark == "00") {
background_color_label?.text = getString(R.string.transparent)
binding.backgroundColorLabel.text = getString(R.string.transparent)
} else {
background_color_label?.text =
binding.backgroundColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getBackgroundColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.backgroundCardAlpha.observe(viewLifecycleOwner, Observer {
viewModel.backgroundCardAlpha.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.backgroundCardAlpha == "00") {
background_color_label?.text = getString(R.string.transparent)
binding.backgroundColorLabel.text = getString(R.string.transparent)
} else {
background_color_label?.text =
binding.backgroundColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getBackgroundColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.backgroundCardAlphaDark.observe(viewLifecycleOwner, Observer {
viewModel.backgroundCardAlphaDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.backgroundCardAlphaDark == "00") {
background_color_label?.text = getString(R.string.transparent)
binding.backgroundColorLabel.text = getString(R.string.transparent)
} else {
background_color_label?.text =
binding.backgroundColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getBackgroundColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
})
}
viewModel.dateFormat.observe(viewLifecycleOwner, Observer {
viewModel.dateFormat.observe(viewLifecycleOwner) {
maintainScrollPosition {
date_format_label?.text = DateHelper.getDateText(requireContext(), Calendar.getInstance())
binding.dateFormatLabel.text = DateHelper.getDateText(requireContext(), Calendar.getInstance())
}
})
}
viewModel.showDividers.observe(viewLifecycleOwner, Observer {
viewModel.showDividers.observe(viewLifecycleOwner) {
maintainScrollPosition {
show_dividers_label?.text =
binding.showDividersLabel.text =
if (it) getString(R.string.settings_visible) else getString(R.string.settings_not_visible)
}
})
}
}
private fun setupListener() {
action_second_row_top_margin_size.setOnClickListener {
binding.actionSecondRowTopMarginSize.setOnClickListener {
BottomSheetMenu<Int>(
requireContext(),
header = getString(R.string.settings_secondary_row_top_margin_title)
@ -191,7 +188,7 @@ class LayoutFragment : Fragment() {
}.show()
}
action_date_format.setOnClickListener {
binding.actionDateFormat.setOnClickListener {
val now = Calendar.getInstance()
val dialog = BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_date_format_title)).setSelectedValue(Preferences.dateFormat)
@ -220,7 +217,7 @@ class LayoutFragment : Fragment() {
}.show()
}
action_background_color.setOnClickListener {
binding.actionBackgroundColor.setOnClickListener {
BottomSheetColorPicker(requireContext(),
colors = colors,
header = getString(R.string.settings_background_color_title),
@ -247,21 +244,21 @@ class LayoutFragment : Fragment() {
).show()
}
action_show_dividers.setOnClickListener {
show_dividers_toggle.isChecked = !show_dividers_toggle.isChecked
binding.actionShowDividers.setOnClickListener {
binding.showDividersToggle.isChecked = !binding.showDividersToggle.isChecked
}
show_dividers_toggle.setOnCheckedChangeListener { _, isChecked ->
binding.showDividersToggle.setOnCheckedChangeListener { _, isChecked ->
Preferences.showDividers = isChecked
}
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}
}

View File

@ -19,15 +19,13 @@ import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
import com.tommasoberlose.anotherwidget.databinding.FragmentTabSelectorBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentPreferencesBinding
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.CalendarHelper
import com.tommasoberlose.anotherwidget.receivers.WeatherReceiver
import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.utils.*
import kotlinx.android.synthetic.main.fragment_tab_selector.*
import kotlinx.android.synthetic.main.fragment_tab_selector.scrollView
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -38,6 +36,7 @@ class PreferencesFragment : Fragment() {
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: FragmentPreferencesBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -52,9 +51,9 @@ class PreferencesFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentTabSelectorBinding>(inflater, R.layout.fragment_preferences, container, false)
binding = FragmentPreferencesBinding.inflate(inflater)
subscribeUi(binding, viewModel)
subscribeUi(viewModel)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -67,13 +66,12 @@ class PreferencesFragment : Fragment() {
setupListener()
scrollView?.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = scrollView?.scrollY ?: 0
binding.scrollView.viewTreeObserver.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = binding.scrollView.scrollY
}
}
private fun subscribeUi(
binding: FragmentTabSelectorBinding,
viewModel: MainViewModel
) {
binding.isCalendarEnabled = Preferences.showEvents
@ -81,7 +79,7 @@ class PreferencesFragment : Fragment() {
binding.isClockVisible = Preferences.showClock
binding.isGlanceVisible = Preferences.showGlance
viewModel.showEvents.observe(viewLifecycleOwner, Observer {
viewModel.showEvents.observe(viewLifecycleOwner) {
maintainScrollPosition {
binding.isCalendarEnabled = it
@ -92,70 +90,70 @@ class PreferencesFragment : Fragment() {
}
}
checkReadEventsPermission()
})
}
viewModel.showWeather.observe(viewLifecycleOwner, Observer {
viewModel.showWeather.observe(viewLifecycleOwner) {
maintainScrollPosition {
binding.isWeatherVisible = it
}
checkLocationPermission()
})
}
viewModel.showClock.observe(viewLifecycleOwner, Observer {
viewModel.showClock.observe(viewLifecycleOwner) {
maintainScrollPosition {
binding.isClockVisible = it
}
})
}
viewModel.showGlance.observe(viewLifecycleOwner, Observer {
viewModel.showGlance.observe(viewLifecycleOwner) {
maintainScrollPosition {
binding.isGlanceVisible = it
}
})
}
}
private fun setupListener() {
action_typography.setOnClickListener {
binding.actionTypography.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_typographyTabFragment)
}
action_general_settings.setOnClickListener {
binding.actionGeneralSettings.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_generalTabFragment)
}
action_show_events.setOnClickListener {
binding.actionShowEvents.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_calendarTabFragment)
}
show_events_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
binding.showEventsSwitch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showEvents = enabled
if (Preferences.showEvents) {
requirePermission()
}
}
action_show_weather.setOnClickListener {
binding.actionShowWeather.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_weatherTabFragment)
}
show_weather_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
binding.showWeatherSwitch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showWeather = enabled
}
action_show_clock.setOnClickListener {
binding.actionShowClock.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_clockTabFragment)
}
show_clock_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
binding.showClockSwitch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showClock = enabled
}
action_show_glance.setOnClickListener {
binding.actionShowGlance.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_tabSelectorFragment_to_glanceTabFragment)
}
show_glance_switch.setOnCheckedChangeListener { _, enabled: Boolean ->
binding.showGlanceSwitch.setOnCheckedChangeListener { _, enabled: Boolean ->
Preferences.showGlance = enabled
}
}
@ -211,11 +209,11 @@ class PreferencesFragment : Fragment() {
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}
}

View File

@ -15,7 +15,7 @@ import com.google.android.material.transition.MaterialSharedAxis
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetColorPicker
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.databinding.FragmentTypographyTabBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentTabTypographyBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
@ -28,8 +28,6 @@ import com.tommasoberlose.anotherwidget.ui.activities.MainActivity
import com.tommasoberlose.anotherwidget.ui.viewmodels.MainViewModel
import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import kotlinx.android.synthetic.main.fragment_typography_tab.*
import kotlinx.android.synthetic.main.fragment_typography_tab.scrollView
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -44,6 +42,8 @@ class TypographyFragment : Fragment() {
private lateinit var viewModel: MainViewModel
private lateinit var colors: IntArray
private lateinit var binding: FragmentTabTypographyBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
@ -56,7 +56,7 @@ class TypographyFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentTypographyTabBinding>(inflater, R.layout.fragment_tab_typography, container, false)
binding = FragmentTabTypographyBinding.inflate(inflater)
subscribeUi(viewModel)
@ -78,8 +78,8 @@ class TypographyFragment : Fragment() {
}
}
scrollView?.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = scrollView?.scrollY ?: 0
binding.scrollView.viewTreeObserver.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = binding.scrollView.scrollY
}
}
@ -91,22 +91,22 @@ class TypographyFragment : Fragment() {
viewModel.textMainSize.observe(viewLifecycleOwner) {
maintainScrollPosition {
main_text_size_label?.text = String.format("%.0fsp", it)
binding.mainTextSizeLabel.text = String.format("%.0fsp", it)
}
}
viewModel.textSecondSize.observe(viewLifecycleOwner) {
maintainScrollPosition {
second_text_size_label?.text = String.format("%.0fsp", it)
binding.secondTextSizeLabel.text = String.format("%.0fsp", it)
}
}
viewModel.textGlobalColor.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textGlobalAlpha == "00") {
font_color_label?.text = getString(R.string.transparent)
binding.fontColorLabel.text = getString(R.string.transparent)
} else {
font_color_label?.text =
binding.fontColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -115,9 +115,9 @@ class TypographyFragment : Fragment() {
viewModel.textGlobalColorDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textGlobalAlphaDark == "00") {
font_color_label_dark?.text = getString(R.string.transparent)
binding.fontColorLabelDark.text = getString(R.string.transparent)
} else {
font_color_label_dark?.text =
binding.fontColorLabelDark.text =
"#%s".format(Integer.toHexString(ColorHelper.getFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -126,9 +126,9 @@ class TypographyFragment : Fragment() {
viewModel.textGlobalAlpha.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textGlobalAlpha == "00") {
font_color_label?.text = getString(R.string.transparent)
binding.fontColorLabel.text = getString(R.string.transparent)
} else {
font_color_label?.text =
binding.fontColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -137,9 +137,9 @@ class TypographyFragment : Fragment() {
viewModel.textGlobalAlphaDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textGlobalAlphaDark == "00") {
font_color_label_dark?.text = getString(R.string.transparent)
binding.fontColorLabelDark.text = getString(R.string.transparent)
} else {
font_color_label_dark?.text =
binding.fontColorLabelDark.text =
"#%s".format(Integer.toHexString(ColorHelper.getFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -148,9 +148,9 @@ class TypographyFragment : Fragment() {
viewModel.textSecondaryColor.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textSecondaryAlpha == "00") {
secondary_font_color_label?.text = getString(R.string.transparent)
binding.secondaryFontColorLabel.text = getString(R.string.transparent)
} else {
secondary_font_color_label?.text =
binding.secondaryFontColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getSecondaryFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -159,9 +159,9 @@ class TypographyFragment : Fragment() {
viewModel.textSecondaryColorDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textSecondaryAlphaDark == "00") {
secondary_font_color_label_dark?.text = getString(R.string.transparent)
binding.secondaryFontColorLabelDark.text = getString(R.string.transparent)
} else {
secondary_font_color_label_dark?.text =
binding.secondaryFontColorLabelDark.text =
"#%s".format(Integer.toHexString(ColorHelper.getSecondaryFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -170,9 +170,9 @@ class TypographyFragment : Fragment() {
viewModel.textSecondaryAlpha.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textSecondaryAlpha == "00") {
secondary_font_color_label?.text = getString(R.string.transparent)
binding.secondaryFontColorLabel.text = getString(R.string.transparent)
} else {
secondary_font_color_label?.text =
binding.secondaryFontColorLabel.text =
"#%s".format(Integer.toHexString(ColorHelper.getSecondaryFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -181,9 +181,9 @@ class TypographyFragment : Fragment() {
viewModel.textSecondaryAlphaDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (Preferences.textSecondaryAlphaDark == "00") {
secondary_font_color_label_dark?.text = getString(R.string.transparent)
binding.secondaryFontColorLabelDark.text = getString(R.string.transparent)
} else {
secondary_font_color_label_dark?.text =
binding.secondaryFontColorLabelDark.text =
"#%s".format(Integer.toHexString(ColorHelper.getSecondaryFontColor(activity?.isDarkTheme() == true))).toUpperCase()
}
}
@ -192,7 +192,7 @@ class TypographyFragment : Fragment() {
viewModel.textShadow.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (activity?.isDarkTheme() != true) {
text_shadow_label?.text =
binding.textShadowLabel.text =
getString(SettingsStringHelper.getTextShadowString(it))
}
}
@ -201,7 +201,7 @@ class TypographyFragment : Fragment() {
viewModel.textShadowDark.observe(viewLifecycleOwner) {
maintainScrollPosition {
if (activity?.isDarkTheme() == true) {
text_shadow_label_dark?.text =
binding.textShadowLabelDark.text =
getString(SettingsStringHelper.getTextShadowString(it))
}
}
@ -209,35 +209,35 @@ class TypographyFragment : Fragment() {
viewModel.customFont.observe(viewLifecycleOwner) {
maintainScrollPosition {
custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), it)
binding.customFontLabel.text = SettingsStringHelper.getCustomFontLabel(requireContext(), it)
MainWidget.updateWidget(requireContext())
}
}
viewModel.customFontFile.observe(viewLifecycleOwner) {
maintainScrollPosition {
custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
binding.customFontLabel.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
MainWidget.updateWidget(requireContext())
}
}
viewModel.customFontName.observe(viewLifecycleOwner) {
maintainScrollPosition {
custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
binding.customFontLabel.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
MainWidget.updateWidget(requireContext())
}
}
viewModel.customFontVariant.observe(viewLifecycleOwner) {
maintainScrollPosition {
custom_font_label?.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
binding.customFontLabel.text = SettingsStringHelper.getCustomFontLabel(requireContext(), Preferences.customFont)
MainWidget.updateWidget(requireContext())
}
}
}
private fun setupListener() {
action_main_text_size.setOnClickListener {
binding.actionMainTextSize.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_main_text_size)).setSelectedValue(
Preferences.textMainSize)
(40 downTo 10).filter { it % 2 == 0 }.forEach {
@ -248,7 +248,7 @@ class TypographyFragment : Fragment() {
}.show()
}
action_second_text_size.setOnClickListener {
binding.actionSecondTextSize.setOnClickListener {
val dialog = BottomSheetMenu<Float>(requireContext(), header = getString(R.string.title_second_text_size)).setSelectedValue(
Preferences.textSecondSize)
(40 downTo 10).filter { it % 2 == 0 }.forEach {
@ -259,7 +259,7 @@ class TypographyFragment : Fragment() {
}.show()
}
action_font_color.setOnClickListener {
binding.actionFontColor.setOnClickListener {
BottomSheetColorPicker(requireContext(),
colors = colors,
header = getString(R.string.settings_font_color_title),
@ -284,7 +284,7 @@ class TypographyFragment : Fragment() {
).show()
}
action_secondary_font_color.setOnClickListener {
binding.actionSecondaryFontColor.setOnClickListener {
BottomSheetColorPicker(requireContext(),
colors = colors,
header = getString(R.string.settings_secondary_font_color_title),
@ -311,7 +311,7 @@ class TypographyFragment : Fragment() {
).show()
}
action_text_shadow.setOnClickListener {
binding.actionTextShadow.setOnClickListener {
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.title_text_shadow)).setSelectedValue(if (activity?.isDarkTheme() == true) Preferences.textShadowDark else Preferences.textShadow)
(2 downTo 0).forEach {
dialog.addItem(getString(SettingsStringHelper.getTextShadowString(it)), it)
@ -325,7 +325,7 @@ class TypographyFragment : Fragment() {
}.show()
}
action_custom_font.setOnClickListener {
binding.actionCustomFont.setOnClickListener {
val dialog = BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_custom_font_title)).setSelectedValue(
Preferences.customFont)
dialog.addItem(SettingsStringHelper.getCustomFontLabel(requireContext(), 0), 0)
@ -357,11 +357,11 @@ class TypographyFragment : Fragment() {
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}
}

View File

@ -24,7 +24,7 @@ import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.components.BottomSheetMenu
import com.tommasoberlose.anotherwidget.components.IconPackSelector
import com.tommasoberlose.anotherwidget.components.MaterialBottomSheetDialog
import com.tommasoberlose.anotherwidget.databinding.FragmentWeatherSettingsBinding
import com.tommasoberlose.anotherwidget.databinding.FragmentTabWeatherBinding
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.global.RequestCode
@ -40,8 +40,6 @@ import com.tommasoberlose.anotherwidget.ui.widgets.MainWidget
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.collapse
import com.tommasoberlose.anotherwidget.utils.expand
import kotlinx.android.synthetic.main.fragment_weather_settings.*
import kotlinx.android.synthetic.main.fragment_weather_settings.scrollView
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@ -52,6 +50,7 @@ class WeatherFragment : Fragment() {
}
private lateinit var viewModel: MainViewModel
private lateinit var binding: FragmentTabWeatherBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -65,9 +64,9 @@ class WeatherFragment : Fragment() {
): View {
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentWeatherSettingsBinding>(inflater, R.layout.fragment_tab_weather, container, false)
binding = FragmentTabWeatherBinding.inflate(inflater)
subscribeUi(binding, viewModel)
subscribeUi(viewModel)
binding.lifecycleOwner = this
binding.viewModel = viewModel
@ -79,83 +78,76 @@ class WeatherFragment : Fragment() {
super.onActivityCreated(savedInstanceState)
setupListener()
scrollView?.viewTreeObserver?.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = scrollView?.scrollY ?: 0
binding.scrollView.viewTreeObserver.addOnScrollChangedListener {
viewModel.fragmentScrollY.value = binding.scrollView.scrollY
}
}
private fun subscribeUi(
binding: FragmentWeatherSettingsBinding,
viewModel: MainViewModel
) {
binding.isWeatherVisible = Preferences.showWeather
viewModel.weatherProvider.observe(viewLifecycleOwner, Observer {
viewModel.weatherProvider.observe(viewLifecycleOwner) {
maintainScrollPosition {
label_weather_provider.text = WeatherHelper.getProviderName(requireContext(), Constants.WeatherProvider.fromInt(it)!!)
binding.labelWeatherProvider.text = WeatherHelper.getProviderName(requireContext(), Constants.WeatherProvider.fromInt(it)!!)
checkWeatherProviderConfig()
}
})
}
viewModel.weatherProviderError.observe(viewLifecycleOwner, Observer {
viewModel.weatherProviderError.observe(viewLifecycleOwner) {
checkWeatherProviderConfig()
})
}
viewModel.weatherProviderLocationError.observe(viewLifecycleOwner, Observer {
viewModel.weatherProviderLocationError.observe(viewLifecycleOwner) {
checkWeatherProviderConfig()
})
}
viewModel.customLocationAdd.observe(viewLifecycleOwner, Observer {
viewModel.customLocationAdd.observe(viewLifecycleOwner) {
maintainScrollPosition {
label_custom_location?.text =
binding.labelCustomLocation.text =
if (it == "") getString(R.string.custom_location_gps) else it
}
checkLocationPermission()
})
}
viewModel.weatherTempUnit.observe(viewLifecycleOwner, Observer {
viewModel.weatherTempUnit.observe(viewLifecycleOwner) {
maintainScrollPosition {
temp_unit?.text =
binding.tempUnit.text =
if (it == "F") getString(R.string.fahrenheit) else getString(R.string.celsius)
}
checkLocationPermission()
})
}
viewModel.weatherRefreshPeriod.observe(viewLifecycleOwner, Observer {
viewModel.weatherRefreshPeriod.observe(viewLifecycleOwner) {
maintainScrollPosition {
label_weather_refresh_period?.text = getString(SettingsStringHelper.getRefreshPeriodString(it))
binding.labelWeatherRefreshPeriod.text = getString(SettingsStringHelper.getRefreshPeriodString(it))
}
checkLocationPermission()
})
}
viewModel.weatherIconPack.observe(viewLifecycleOwner, Observer {
viewModel.weatherIconPack.observe(viewLifecycleOwner) {
maintainScrollPosition {
label_weather_icon_pack?.text = getString(R.string.settings_weather_icon_pack_default).format((it + 1))
// weather_icon_pack.setImageDrawable(ContextCompat.getDrawable(requireContext(), WeatherHelper.getWeatherIconResource("02d")))
// if (it == Constants.WeatherIconPack.MINIMAL.value) {
// weather_icon_pack.setColorFilter(ContextCompat.getColor(requireContext(), R.color.colorPrimaryText))
// } else {
// weather_icon_pack.setColorFilter(ContextCompat.getColor(requireContext(), android.R.color.transparent))
// }
binding.labelWeatherIconPack.text = getString(R.string.settings_weather_icon_pack_default).format((it + 1))
}
checkLocationPermission()
})
}
viewModel.weatherAppName.observe(viewLifecycleOwner, Observer {
viewModel.weatherAppName.observe(viewLifecycleOwner) {
maintainScrollPosition {
weather_app_label?.text =
binding.weatherAppLabel.text =
if (it != "") it else getString(R.string.default_weather_app)
}
})
}
}
private fun checkLocationPermission() {
if (requireActivity().checkGrantedPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
location_permission_alert?.isVisible = false
binding.locationPermissionAlert.isVisible = false
WeatherReceiver.setUpdates(requireContext())
} else if (Preferences.showWeather && Preferences.customLocationAdd == "") {
location_permission_alert?.isVisible = true
location_permission_alert?.setOnClickListener {
binding.locationPermissionAlert.isVisible = true
binding.locationPermissionAlert.setOnClickListener {
MaterialBottomSheetDialog(requireContext(), message = getString(R.string.background_location_warning))
.setPositiveButton(getString(android.R.string.ok)) {
requirePermission()
@ -163,43 +155,43 @@ class WeatherFragment : Fragment() {
.show()
}
} else {
location_permission_alert?.isVisible = false
binding.locationPermissionAlert.isVisible = false
}
}
private fun checkWeatherProviderConfig() {
if (Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" && !location_permission_alert.isVisible) {
weather_provider_error.expand()
if (Preferences.showWeather && Preferences.weatherProviderError != "" && Preferences.weatherProviderError != "-" && !binding.locationPermissionAlert.isVisible) {
binding.weatherProviderError.expand()
} else {
weather_provider_error.collapse()
binding.weatherProviderError.collapse()
}
weather_provider_error?.text = Preferences.weatherProviderError
binding.weatherProviderError.text = Preferences.weatherProviderError
if (Preferences.showWeather && Preferences.weatherProviderLocationError != "" && !location_permission_alert.isVisible) {
weather_provider_location_error.expand()
if (Preferences.showWeather && Preferences.weatherProviderLocationError != "" && !binding.locationPermissionAlert.isVisible) {
binding.weatherProviderLocationError.expand()
} else {
weather_provider_location_error.collapse()
binding.weatherProviderLocationError.collapse()
}
weather_provider_location_error?.text = Preferences.weatherProviderLocationError
binding.weatherProviderLocationError.text = Preferences.weatherProviderLocationError
}
private fun setupListener() {
action_weather_provider.setOnClickListener {
binding.actionWeatherProvider.setOnClickListener {
startActivityForResult(
Intent(requireContext(), WeatherProviderActivity::class.java),
RequestCode.WEATHER_PROVIDER_REQUEST_CODE.code
)
}
action_custom_location.setOnClickListener {
binding.actionCustomLocation.setOnClickListener {
startActivityForResult(
Intent(requireContext(), CustomLocationActivity::class.java),
Constants.RESULT_CODE_CUSTOM_LOCATION
)
}
action_change_unit.setOnClickListener {
binding.actionChangeUnit.setOnClickListener {
BottomSheetMenu<String>(requireContext(), header = getString(R.string.settings_unit_title)).setSelectedValue(Preferences.weatherTempUnit)
.addItem(getString(R.string.fahrenheit), "F")
.addItem(getString(R.string.celsius), "C")
@ -213,7 +205,7 @@ class WeatherFragment : Fragment() {
}.show()
}
action_weather_refresh_period.setOnClickListener {
binding.actionWeatherRefreshPeriod.setOnClickListener {
val dialog =
BottomSheetMenu<Int>(requireContext(), header = getString(R.string.settings_weather_refresh_period_title)).setSelectedValue(Preferences.weatherRefreshPeriod)
(5 downTo 0).forEach {
@ -225,11 +217,11 @@ class WeatherFragment : Fragment() {
}.show()
}
action_weather_icon_pack.setOnClickListener {
binding.actionWeatherIconPack.setOnClickListener {
IconPackSelector(requireContext(), header = getString(R.string.settings_weather_icon_pack_title)).show()
}
action_weather_app.setOnClickListener {
binding.actionWeatherApp.setOnClickListener {
startActivityForResult(
Intent(requireContext(), ChooseApplicationActivity::class.java),
RequestCode.WEATHER_APP_REQUEST_CODE.code
@ -284,11 +276,11 @@ class WeatherFragment : Fragment() {
}
private fun maintainScrollPosition(callback: () -> Unit) {
scrollView.isScrollable = false
binding.scrollView.isScrollable = false
callback.invoke()
lifecycleScope.launch {
delay(200)
scrollView.isScrollable = true
binding.scrollView.isScrollable = true
}
}
}

View File

@ -15,6 +15,7 @@ import android.os.Bundle
import android.text.format.DateUtils
import android.util.Log
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.RemoteViews
@ -23,6 +24,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.google.gson.Gson
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.databinding.TheWidgetBinding
import com.tommasoberlose.anotherwidget.db.EventRepository
import com.tommasoberlose.anotherwidget.global.Actions
import com.tommasoberlose.anotherwidget.global.Constants
@ -34,7 +36,6 @@ import com.tommasoberlose.anotherwidget.receivers.*
import com.tommasoberlose.anotherwidget.utils.checkGrantedPermission
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
import com.tommasoberlose.anotherwidget.utils.toPixel
import kotlinx.android.synthetic.main.the_widget.view.*
import java.text.DateFormat
import java.util.*
import java.util.concurrent.TimeUnit
@ -133,13 +134,13 @@ class MainWidget : AppWidgetProvider() {
// Setup listener
try {
val generatedView = generateWidgetView(context, typeface)
val generatedBinding = generateWidgetView(context, typeface)
views.setImageViewBitmap(
R.id.bitmap_container,
BitmapHelper.getBitmapFromView(generatedView, width = w)
BitmapHelper.getBitmapFromView(generatedBinding.root, width = w)
)
views = updateCalendarView(context, generatedView, views, appWidgetId)
views = updateWeatherView(context, generatedView, views, appWidgetId)
views = updateCalendarView(context, generatedBinding, views, appWidgetId)
views = updateWeatherView(context, generatedBinding, views, appWidgetId)
} catch (ex: Exception) {
ex.printStackTrace()
CrashlyticsReceiver.sendCrash(context, ex)
@ -148,12 +149,12 @@ class MainWidget : AppWidgetProvider() {
appWidgetManager.updateAppWidget(appWidgetId, views)
}
private fun updateCalendarView(context: Context, v: View, views: RemoteViews, widgetID: Int): RemoteViews {
private fun updateCalendarView(context: Context, bindingView: TheWidgetBinding, views: RemoteViews, widgetID: Int): RemoteViews {
val eventRepository = EventRepository(context)
try {
views.setImageViewBitmap(
R.id.empty_date_rect,
BitmapHelper.getBitmapFromView(v.empty_date, draw = false)
BitmapHelper.getBitmapFromView(bindingView.emptyDate, draw = false)
)
views.setViewVisibility(R.id.empty_layout_rect, View.VISIBLE)
@ -176,7 +177,7 @@ class MainWidget : AppWidgetProvider() {
if (Preferences.showNextEvent && eventRepository.getEventsCount() > 1) {
views.setImageViewBitmap(
R.id.action_next_rect,
BitmapHelper.getBitmapFromView(v.action_next, draw = false)
BitmapHelper.getBitmapFromView(bindingView.actionNext, draw = false)
)
views.setViewVisibility(R.id.action_next_rect, View.VISIBLE)
views.setOnClickPendingIntent(
@ -194,7 +195,7 @@ class MainWidget : AppWidgetProvider() {
views.setImageViewBitmap(
R.id.action_previous_rect,
BitmapHelper.getBitmapFromView(v.action_previous, draw = false)
BitmapHelper.getBitmapFromView(bindingView.actionPrevious, draw = false)
)
views.setViewVisibility(R.id.action_previous_rect, View.VISIBLE)
views.setOnClickPendingIntent(
@ -227,7 +228,7 @@ class MainWidget : AppWidgetProvider() {
views.setImageViewBitmap(
R.id.next_event_difference_time_rect,
BitmapHelper.getBitmapFromView(
v.next_event_difference_time,
bindingView.nextEventDifferenceTime,
draw = false
)
)
@ -260,12 +261,12 @@ class MainWidget : AppWidgetProvider() {
views.setImageViewBitmap(
R.id.next_event_rect,
BitmapHelper.getBitmapFromView(v.next_event, draw = false)
BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false)
)
views.setImageViewBitmap(
R.id.second_row_rect,
BitmapHelper.getBitmapFromView(v.second_row, draw = false)
BitmapHelper.getBitmapFromView(bindingView.secondRow, draw = false)
)
views.setViewVisibility(R.id.second_row_rect, View.VISIBLE)
@ -284,7 +285,7 @@ class MainWidget : AppWidgetProvider() {
R.id.second_row_top_margin_large_sans,
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE
)
} else if (GlanceProviderHelper.showGlanceProviders(context) && v.calendar_layout.isVisible) {
} else if (GlanceProviderHelper.showGlanceProviders(context) && bindingView.calendarLayout.isVisible) {
var showSomething = false
loop@ for (provider:Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(context)) {
when (provider) {
@ -405,12 +406,12 @@ class MainWidget : AppWidgetProvider() {
if (showSomething) {
views.setImageViewBitmap(
R.id.next_event_rect,
BitmapHelper.getBitmapFromView(v.next_event, draw = false)
BitmapHelper.getBitmapFromView(bindingView.nextEvent, draw = false)
)
views.setImageViewBitmap(
R.id.second_row_rect,
BitmapHelper.getBitmapFromView(v.second_row, draw = false)
BitmapHelper.getBitmapFromView(bindingView.secondRow, draw = false)
)
views.setViewVisibility(R.id.second_row_rect, View.VISIBLE)
@ -443,7 +444,7 @@ class MainWidget : AppWidgetProvider() {
return views
}
private fun updateWeatherView(context: Context, v: View, views: RemoteViews, widgetID: Int): RemoteViews {
private fun updateWeatherView(context: Context, bindingView: TheWidgetBinding, views: RemoteViews, widgetID: Int): RemoteViews {
try {
if (Preferences.showWeather && Preferences.weatherIcon != "") {
views.setViewVisibility(R.id.weather_rect, View.VISIBLE)
@ -460,17 +461,17 @@ class MainWidget : AppWidgetProvider() {
views.setImageViewBitmap(
R.id.weather_rect,
BitmapHelper.getBitmapFromView(v.weather, draw = false)
BitmapHelper.getBitmapFromView(bindingView.weather, draw = false)
)
views.setImageViewBitmap(
R.id.calendar_weather_rect,
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
BitmapHelper.getBitmapFromView(bindingView.calendarWeather, draw = false)
)
views.setImageViewBitmap(
R.id.special_weather_rect,
BitmapHelper.getBitmapFromView(v.calendar_weather, draw = false)
BitmapHelper.getBitmapFromView(bindingView.calendarWeather, draw = false)
)
if (GlanceProviderHelper.showGlanceProviders(context)) {
@ -550,39 +551,39 @@ class MainWidget : AppWidgetProvider() {
// Generates the widget bitmap from the view
fun generateWidgetView(context: Context, typeface: Typeface? = null): View {
fun generateWidgetView(context: Context, typeface: Typeface? = null): TheWidgetBinding {
val eventRepository = EventRepository(context)
val v = View.inflate(context, R.layout.the_widget, null)
val bindingView = TheWidgetBinding.inflate(LayoutInflater.from(context))
v.loader.isVisible = false
bindingView.loader.isVisible = false
val now = Calendar.getInstance().apply {
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}
v.empty_layout.visibility = View.VISIBLE
v.calendar_layout.visibility = View.GONE
v.next_event_difference_time.visibility = View.GONE
v.action_next.isVisible = false
v.action_previous.isVisible = false
bindingView.emptyLayout.visibility = View.VISIBLE
bindingView.calendarLayout.visibility = View.GONE
bindingView.nextEventDifferenceTime.visibility = View.GONE
bindingView.actionNext.isVisible = false
bindingView.actionPrevious.isVisible = false
v.empty_date.text = DateHelper.getDateText(context, now)
bindingView.emptyDate.text = DateHelper.getDateText(context, now)
val nextEvent = eventRepository.getNextEvent()
val nextAlarm = AlarmHelper.getNextAlarm(context)
if (Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null && !Preferences.showEventsAsGlanceProvider) {
// Multiple counter
v.action_next.isVisible =
bindingView.actionNext.isVisible =
Preferences.showNextEvent && eventRepository.getEventsCount() > 1
v.action_previous.isVisible =
bindingView.actionPrevious.isVisible =
Preferences.showNextEvent && eventRepository.getEventsCount() > 1
v.next_event.text = nextEvent.title
bindingView.nextEvent.text = nextEvent.title
if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
v.next_event_difference_time.text = if (!nextEvent.allDay) {
bindingView.nextEventDifferenceTime.text = if (!nextEvent.allDay) {
SettingsStringHelper.getDifferenceText(
context,
now.timeInMillis,
@ -596,21 +597,21 @@ class MainWidget : AppWidgetProvider() {
nextEvent.startDate
).toLowerCase(Locale.getDefault())
}
v.next_event_difference_time.visibility = View.VISIBLE
bindingView.nextEventDifferenceTime.visibility = View.VISIBLE
} else {
v.next_event_difference_time.visibility = View.GONE
bindingView.nextEventDifferenceTime.visibility = View.GONE
}
if (nextEvent.address != "" && Preferences.secondRowInformation == 1) {
v.second_row_icon.setImageDrawable(
bindingView.secondRowIcon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_place_24
)
)
v.next_event_date.text = nextEvent.address
bindingView.nextEventDate.text = nextEvent.address
} else {
v.second_row_icon.setImageDrawable(
bindingView.secondRowIcon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_today_24
@ -651,10 +652,10 @@ class MainWidget : AppWidgetProvider() {
}
if (nextEvent.startDate != nextEvent.endDate) {
v.next_event_date.text =
bindingView.nextEventDate.text =
String.format("%s - %s%s", startHour, endHour, multipleDay)
} else {
v.next_event_date.text =
bindingView.nextEventDate.text =
String.format("%s", startHour)
}
@ -663,7 +664,7 @@ class MainWidget : AppWidgetProvider() {
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_NO_YEAR or DateUtils.FORMAT_ABBREV_MONTH
val start = Calendar.getInstance().apply { timeInMillis = nextEvent.startDate }
v.next_event_date.text = if (now.get(Calendar.DAY_OF_YEAR) == start.get(Calendar.DAY_OF_YEAR)) {
bindingView.nextEventDate.text = if (now.get(Calendar.DAY_OF_YEAR) == start.get(Calendar.DAY_OF_YEAR)) {
DateUtils.formatDateTime(context, nextEvent.startDate, flags)
} else if (now.get(Calendar.DAY_OF_YEAR) > start.get(Calendar.DAY_OF_YEAR) || now.get(Calendar.YEAR) > start.get(Calendar.YEAR)) {
DateUtils.formatDateTime(context, now.timeInMillis, flags)
@ -673,17 +674,17 @@ class MainWidget : AppWidgetProvider() {
}
}
v.empty_layout.visibility = View.GONE
v.calendar_layout.visibility = View.VISIBLE
bindingView.emptyLayout.visibility = View.GONE
bindingView.calendarLayout.visibility = View.VISIBLE
v.second_row_top_margin_small.visibility =
bindingView.secondRowTopMarginSmall.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE
v.second_row_top_margin_medium.visibility =
bindingView.secondRowTopMarginMedium.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE
v.second_row_top_margin_large.visibility =
bindingView.secondRowTopMarginLarge.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE
} else if (GlanceProviderHelper.showGlanceProviders(context)) {
v.second_row_icon.isVisible = true
bindingView.secondRowIcon.isVisible = true
var showSomething = false
loop@ for (provider: Constants.GlanceProviderId in GlanceProviderHelper.getGlanceProviders(
context
@ -691,26 +692,26 @@ class MainWidget : AppWidgetProvider() {
when (provider) {
Constants.GlanceProviderId.PLAYING_SONG -> {
if (MediaPlayerHelper.isSomeonePlaying(context)) {
v.second_row_icon.setImageDrawable(
bindingView.secondRowIcon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_music_note_24
)
)
v.next_event_date.text = MediaPlayerHelper.getMediaInfo()
bindingView.nextEventDate.text = MediaPlayerHelper.getMediaInfo()
showSomething = true
break@loop
}
}
Constants.GlanceProviderId.NEXT_CLOCK_ALARM -> {
if (Preferences.showNextAlarm && nextAlarm != "") {
v.second_row_icon.setImageDrawable(
bindingView.secondRowIcon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_alarm_24
)
)
v.next_event_date.text = AlarmHelper.getNextAlarm(context)
bindingView.nextEventDate.text = AlarmHelper.getNextAlarm(context)
showSomething = true
break@loop
}
@ -719,19 +720,19 @@ class MainWidget : AppWidgetProvider() {
if (Preferences.showBatteryCharging) {
BatteryHelper.updateBatteryInfo(context)
if (Preferences.isCharging) {
v.second_row_icon.isVisible = false
bindingView.secondRowIcon.isVisible = false
val batteryLevel = BatteryHelper.getBatteryLevel(context)
if (batteryLevel != 100) {
v.next_event_date.text = context.getString(R.string.charging)
bindingView.nextEventDate.text = context.getString(R.string.charging)
} else {
v.next_event_date.text =
bindingView.nextEventDate.text =
context.getString(R.string.charged)
}
showSomething = true
break@loop
} else if (Preferences.isBatteryLevelLow) {
v.second_row_icon.isVisible = false
v.next_event_date.text =
bindingView.secondRowIcon.isVisible = false
bindingView.nextEventDate.text =
context.getString(R.string.battery_low_warning)
showSomething = true
break@loop
@ -740,17 +741,17 @@ class MainWidget : AppWidgetProvider() {
}
Constants.GlanceProviderId.CUSTOM_INFO -> {
if (Preferences.customNotes.isNotEmpty()) {
v.second_row_icon.isVisible = false
v.next_event_date.text = Preferences.customNotes
v.next_event_date.maxLines = 2
bindingView.secondRowIcon.isVisible = false
bindingView.nextEventDate.text = Preferences.customNotes
bindingView.nextEventDate.maxLines = 2
showSomething = true
break@loop
}
}
Constants.GlanceProviderId.GOOGLE_FIT_STEPS -> {
if (Preferences.showDailySteps && Preferences.googleFitSteps > 0) {
v.second_row_icon.isVisible = false
v.next_event_date.text =
bindingView.secondRowIcon.isVisible = false
bindingView.nextEventDate.text =
context.getString(R.string.daily_steps_counter)
.format(Preferences.googleFitSteps)
showSomething = true
@ -764,12 +765,12 @@ class MainWidget : AppWidgetProvider() {
val remotePackageContext = context.createPackageContext(Preferences.lastNotificationPackage, 0)
val icon = ContextCompat.getDrawable(remotePackageContext,
Preferences.lastNotificationIcon)
v.second_row_icon.isVisible = true
v.second_row_icon.setImageDrawable(icon)
bindingView.secondRowIcon.isVisible = true
bindingView.secondRowIcon.setImageDrawable(icon)
} else {
v.second_row_icon.isVisible = false
bindingView.secondRowIcon.isVisible = false
}
v.next_event_date.text = Preferences.lastNotificationTitle
bindingView.nextEventDate.text = Preferences.lastNotificationTitle
showSomething = true
break@loop
} catch (ex: Exception) {}
@ -778,16 +779,16 @@ class MainWidget : AppWidgetProvider() {
Constants.GlanceProviderId.GREETINGS -> {
val greetingsText = GreetingsHelper.getRandomString(context)
if (Preferences.showGreetings && GreetingsHelper.showGreetings() && greetingsText.isNotBlank()) {
v.next_event_date.text = greetingsText
v.next_event_date.maxLines = 2
v.second_row_icon.isVisible = false
bindingView.nextEventDate.text = greetingsText
bindingView.nextEventDate.maxLines = 2
bindingView.secondRowIcon.isVisible = false
showSomething = true
break@loop
}
}
Constants.GlanceProviderId.EVENTS -> {
if (Preferences.showEventsAsGlanceProvider && Preferences.showEvents && context.checkGrantedPermission(Manifest.permission.READ_CALENDAR) && nextEvent != null) {
v.next_event_date.text = context.getString(R.string.events_glance_provider_format).format(nextEvent.title, if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
bindingView.nextEventDate.text = context.getString(R.string.events_glance_provider_format).format(nextEvent.title, if (Preferences.showDiffTime && now.timeInMillis < nextEvent.startDate) {
if (!nextEvent.allDay) {
SettingsStringHelper.getDifferenceText(
context,
@ -803,8 +804,8 @@ class MainWidget : AppWidgetProvider() {
).toLowerCase(Locale.getDefault())
}
} else "").trimEnd()
v.second_row_icon.isVisible = true
v.second_row_icon.setImageDrawable(
bindingView.secondRowIcon.isVisible = true
bindingView.secondRowIcon.setImageDrawable(
ContextCompat.getDrawable(
context,
R.drawable.round_today_24
@ -818,43 +819,43 @@ class MainWidget : AppWidgetProvider() {
}
if (showSomething) {
v.next_event.text = DateHelper.getDateText(context, now)
v.empty_layout.visibility = View.GONE
v.calendar_layout.visibility = View.VISIBLE
bindingView.nextEvent.text = DateHelper.getDateText(context, now)
bindingView.emptyLayout.visibility = View.GONE
bindingView.calendarLayout.visibility = View.VISIBLE
v.second_row_top_margin_small.visibility =
bindingView.secondRowTopMarginSmall.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.SMALL.value) View.VISIBLE else View.GONE
v.second_row_top_margin_medium.visibility =
bindingView.secondRowTopMarginMedium.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.MEDIUM.value) View.VISIBLE else View.GONE
v.second_row_top_margin_large.visibility =
bindingView.secondRowTopMarginLarge.visibility =
if (Preferences.secondRowTopMargin == Constants.SecondRowTopMargin.LARGE.value) View.VISIBLE else View.GONE
} else {
v.second_row_icon.isVisible = false
bindingView.secondRowIcon.isVisible = false
}
}
// Color
listOf<TextView>(
v.empty_date,
v.divider1,
v.temp,
v.next_event,
v.next_event_difference_time,
v.divider3,
v.special_temp
bindingView.emptyDate,
bindingView.divider1,
bindingView.temp,
bindingView.nextEvent,
bindingView.nextEventDifferenceTime,
bindingView.divider3,
bindingView.specialTemp
).forEach {
it.setTextColor(ColorHelper.getFontColor(context.applicationContext.isDarkTheme()))
}
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) {
listOf<ImageView>(v.action_next, v.action_previous)
listOf<ImageView>(bindingView.actionNext, bindingView.actionPrevious)
} else {
listOf<ImageView>(
v.action_next,
v.action_previous,
v.empty_weather_icon,
v.special_weather_icon
bindingView.actionNext,
bindingView.actionPrevious,
bindingView.emptyWeatherIcon,
bindingView.specialWeatherIcon
)
}.forEach {
it.setColorFilter(ColorHelper.getFontColorRgb(context.applicationContext.isDarkTheme()))
@ -864,14 +865,14 @@ class MainWidget : AppWidgetProvider() {
.toFloat()) / 100
}
listOf<TextView>(v.next_event_date, v.divider2, v.calendar_temp).forEach {
listOf<TextView>(bindingView.nextEventDate, bindingView.divider2, bindingView.calendarTemp).forEach {
it.setTextColor(ColorHelper.getSecondaryFontColor(context.applicationContext.isDarkTheme()))
}
if (Preferences.weatherIconPack != Constants.WeatherIconPack.MINIMAL.value) {
listOf<ImageView>(v.second_row_icon, v.second_row_icon_shadow)
listOf<ImageView>(bindingView.secondRowIcon, bindingView.secondRowIconShadow)
} else {
listOf<ImageView>(v.second_row_icon, v.weather_icon, v.second_row_icon_shadow)
listOf<ImageView>(bindingView.secondRowIcon, bindingView.weatherIcon, bindingView.secondRowIconShadow)
}.forEach {
it.setColorFilter(ColorHelper.getSecondaryFontColorRgb(context.applicationContext.isDarkTheme()))
it.alpha =
@ -882,38 +883,38 @@ class MainWidget : AppWidgetProvider() {
// Text Size
listOf<Pair<TextView, Float>>(
v.empty_date to Preferences.textMainSize,
v.divider1 to (Preferences.textMainSize - 2),
v.temp to Preferences.textMainSize,
v.next_event to Preferences.textMainSize,
v.next_event_difference_time to Preferences.textMainSize,
v.next_event_date to Preferences.textSecondSize,
v.divider2 to (Preferences.textSecondSize - 2),
v.calendar_temp to Preferences.textSecondSize,
v.divider3 to (Preferences.textMainSize - 2),
v.special_temp to Preferences.textMainSize
bindingView.emptyDate to Preferences.textMainSize,
bindingView.divider1 to (Preferences.textMainSize - 2),
bindingView.temp to Preferences.textMainSize,
bindingView.nextEvent to Preferences.textMainSize,
bindingView.nextEventDifferenceTime to Preferences.textMainSize,
bindingView.nextEventDate to Preferences.textSecondSize,
bindingView.divider2 to (Preferences.textSecondSize - 2),
bindingView.calendarTemp to Preferences.textSecondSize,
bindingView.divider3 to (Preferences.textMainSize - 2),
bindingView.specialTemp to Preferences.textMainSize
).forEach {
it.first.setTextSize(TypedValue.COMPLEX_UNIT_SP, it.second)
}
// Icons scale
v.second_row_icon.scaleX = Preferences.textSecondSize / 18f
v.second_row_icon.scaleY = Preferences.textSecondSize / 18f
bindingView.secondRowIcon.scaleX = Preferences.textSecondSize / 18f
bindingView.secondRowIcon.scaleY = Preferences.textSecondSize / 18f
v.weather_icon.scaleX = Preferences.textSecondSize / 14f
v.weather_icon.scaleY = Preferences.textSecondSize / 14f
bindingView.weatherIcon.scaleX = Preferences.textSecondSize / 14f
bindingView.weatherIcon.scaleY = Preferences.textSecondSize / 14f
v.empty_weather_icon.scaleX = Preferences.textMainSize / 18f
v.empty_weather_icon.scaleY = Preferences.textMainSize / 18f
bindingView.emptyWeatherIcon.scaleX = Preferences.textMainSize / 18f
bindingView.emptyWeatherIcon.scaleY = Preferences.textMainSize / 18f
v.action_next.scaleX = Preferences.textMainSize / 28f
v.action_next.scaleY = Preferences.textMainSize / 28f
bindingView.actionNext.scaleX = Preferences.textMainSize / 28f
bindingView.actionNext.scaleY = Preferences.textMainSize / 28f
v.action_previous.scaleX = Preferences.textMainSize / 28f
v.action_previous.scaleY = Preferences.textMainSize / 28f
bindingView.actionPrevious.scaleX = Preferences.textMainSize / 28f
bindingView.actionPrevious.scaleY = Preferences.textMainSize / 28f
v.special_weather_icon.scaleX = Preferences.textMainSize / 18f
v.special_weather_icon.scaleY = Preferences.textMainSize / 18f
bindingView.specialWeatherIcon.scaleX = Preferences.textMainSize / 18f
bindingView.specialWeatherIcon.scaleY = Preferences.textMainSize / 18f
// Shadows
@ -940,16 +941,16 @@ class MainWidget : AppWidgetProvider() {
}
listOf<TextView>(
v.empty_date,
v.divider1,
v.temp,
v.next_event,
v.next_event_difference_time,
v.next_event_date,
v.divider2,
v.calendar_temp,
v.divider3,
v.special_temp
bindingView.emptyDate,
bindingView.divider1,
bindingView.temp,
bindingView.nextEvent,
bindingView.nextEventDifferenceTime,
bindingView.nextEventDate,
bindingView.divider2,
bindingView.calendarTemp,
bindingView.divider3,
bindingView.specialTemp
).forEach {
it.setShadowLayer(shadowRadius, 0f, shadowDy, shadowColor)
}
@ -957,7 +958,7 @@ class MainWidget : AppWidgetProvider() {
// Icons shadow
listOf(
Pair(v.second_row_icon, v.second_row_icon_shadow),
Pair(bindingView.secondRowIcon, bindingView.secondRowIconShadow),
).forEach {
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
it.second.isVisible = false
@ -970,8 +971,8 @@ class MainWidget : AppWidgetProvider() {
}
listOf(
Pair(v.action_next, v.action_next_shadow),
Pair(v.action_previous, v.action_previous_shadow),
Pair(bindingView.actionNext, bindingView.actionNextShadow),
Pair(bindingView.actionPrevious, bindingView.actionPreviousShadow),
).forEach {
if ((if (context.isDarkTheme()) Preferences.textShadowDark else Preferences.textShadow) == 0) {
it.second.isVisible = false
@ -983,8 +984,8 @@ class MainWidget : AppWidgetProvider() {
}
}
v.action_previous.scaleX = v.action_previous.scaleX * -1
v.action_previous_shadow.scaleX = v.action_previous_shadow.scaleX * -1
bindingView.actionPrevious.scaleX = bindingView.actionPrevious.scaleX * -1
bindingView.actionPreviousShadow.scaleX = bindingView.actionPreviousShadow.scaleX * -1
// Custom Font
if (Preferences.customFont == Constants.CUSTOM_FONT_GOOGLE_SANS) {
@ -998,31 +999,31 @@ class MainWidget : AppWidgetProvider() {
}
listOf<TextView>(
v.empty_date,
v.divider1,
v.temp,
v.next_event,
v.next_event_difference_time,
v.next_event_date,
v.divider2,
v.calendar_temp,
v.divider3,
v.special_temp
bindingView.emptyDate,
bindingView.divider1,
bindingView.temp,
bindingView.nextEvent,
bindingView.nextEventDifferenceTime,
bindingView.nextEventDate,
bindingView.divider2,
bindingView.calendarTemp,
bindingView.divider3,
bindingView.specialTemp
).forEach {
it.typeface = googleSans
}
} else if (Preferences.customFont == Constants.CUSTOM_FONT_DOWNLOADED && typeface != null) {
listOf<TextView>(
v.empty_date,
v.divider1,
v.temp,
v.next_event,
v.next_event_difference_time,
v.next_event_date,
v.divider2,
v.calendar_temp,
v.divider3,
v.special_temp
bindingView.emptyDate,
bindingView.divider1,
bindingView.temp,
bindingView.nextEvent,
bindingView.nextEventDifferenceTime,
bindingView.nextEventDate,
bindingView.divider2,
bindingView.calendarTemp,
bindingView.divider3,
bindingView.specialTemp
).forEach {
it.typeface = typeface
}
@ -1030,9 +1031,9 @@ class MainWidget : AppWidgetProvider() {
// Weather
if (Preferences.showWeather && Preferences.weatherIcon != "") {
v.weather.visibility = View.VISIBLE
v.calendar_weather.visibility = View.VISIBLE
v.special_weather.visibility = View.VISIBLE
bindingView.weather.visibility = View.VISIBLE
bindingView.calendarWeather.visibility = View.VISIBLE
bindingView.specialWeather.visibility = View.VISIBLE
val currentTemp = String.format(
Locale.getDefault(),
"%d °%s",
@ -1042,41 +1043,41 @@ class MainWidget : AppWidgetProvider() {
val icon: String = Preferences.weatherIcon
if (icon == "") {
v.weather_icon.visibility = View.GONE
v.empty_weather_icon.visibility = View.GONE
v.special_weather_icon.visibility = View.GONE
bindingView.weatherIcon.visibility = View.GONE
bindingView.emptyWeatherIcon.visibility = View.GONE
bindingView.specialWeatherIcon.visibility = View.GONE
} else {
v.weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
v.empty_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
v.special_weather_icon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
v.weather_icon.visibility = View.VISIBLE
v.empty_weather_icon.visibility = View.VISIBLE
v.special_weather_icon.visibility = View.VISIBLE
bindingView.weatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
bindingView.emptyWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
bindingView.specialWeatherIcon.setImageResource(WeatherHelper.getWeatherIconResource(context, icon))
bindingView.weatherIcon.visibility = View.VISIBLE
bindingView.emptyWeatherIcon.visibility = View.VISIBLE
bindingView.specialWeatherIcon.visibility = View.VISIBLE
}
v.temp.text = currentTemp
v.calendar_temp.text = currentTemp
v.special_temp.text = currentTemp
bindingView.temp.text = currentTemp
bindingView.calendarTemp.text = currentTemp
bindingView.specialTemp.text = currentTemp
if (GlanceProviderHelper.showGlanceProviders(context)) {
v.calendar_weather.visibility = View.GONE
bindingView.calendarWeather.visibility = View.GONE
} else {
v.special_weather.visibility = View.GONE
bindingView.specialWeather.visibility = View.GONE
}
} else {
v.weather.visibility = View.GONE
v.calendar_weather.visibility = View.GONE
v.special_weather.visibility = View.GONE
bindingView.weather.visibility = View.GONE
bindingView.calendarWeather.visibility = View.GONE
bindingView.specialWeather.visibility = View.GONE
}
// Dividers
arrayOf(v.divider1, v.divider2, v.divider3).forEach {
arrayOf(bindingView.divider1, bindingView.divider2, bindingView.divider3).forEach {
it.isVisible = Preferences.showDividers
}
eventRepository.close()
return v
return bindingView
}
}
}

View File

@ -2,7 +2,6 @@ package com.tommasoberlose.anotherwidget.utils
import android.animation.*
import android.content.pm.PackageManager
import android.view.Gravity
import android.view.View
import android.view.ViewAnimationUtils
import android.widget.Toast
@ -21,22 +20,12 @@ import android.content.Intent
import android.content.res.Resources
import android.graphics.drawable.Drawable
import android.util.DisplayMetrics
import android.util.Log
import android.util.TypedValue
import android.view.ViewPropertyAnimator
import android.view.animation.Animation
import android.view.animation.Transformation
import android.widget.LinearLayout
import android.widget.RelativeLayout
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.core.animation.addListener
import androidx.core.animation.doOnEnd
import androidx.core.animation.doOnStart
import androidx.core.view.isVisible
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.ui.fragments.MainFragment
import kotlinx.android.synthetic.main.fragment_app_main.*
import kotlinx.android.synthetic.main.the_widget_sans.*
import java.util.*
@ -149,7 +138,7 @@ fun View.collapse(duration: Long = 500L) {
fun Context.openURI(url: String) {
try {
val builder: CustomTabsIntent.Builder = CustomTabsIntent.Builder()
builder.setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary))
builder.setDefaultColorSchemeParams(CustomTabColorSchemeParams.Builder().setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimary)).build())
val customTabsIntent: CustomTabsIntent = builder.build()
customTabsIntent.launchUrl(this, Uri.parse(url))
} catch (e: Exception) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M4,13h6c0.55,0 1,-0.45 1,-1L11,4c0,-0.55 -0.45,-1 -1,-1L4,3c-0.55,0 -1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM4,21h6c0.55,0 1,-0.45 1,-1v-4c0,-0.55 -0.45,-1 -1,-1L4,15c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1zM14,21h6c0.55,0 1,-0.45 1,-1v-8c0,-0.55 -0.45,-1 -1,-1h-6c-0.55,0 -1,0.45 -1,1v8c0,0.55 0.45,1 1,1zM13,4v4c0,0.55 0.45,1 1,1h6c0.55,0 1,-0.45 1,-1L21,4c0,-0.55 -0.45,-1 -1,-1h-6c-0.55,0 -1,0.45 -1,1z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19.3,16.9c0.58,-1.01 0.95,-2.23 0.51,-3.65c-0.53,-1.72 -2.04,-3.05 -3.84,-3.22c-2.87,-0.28 -5.23,2.07 -4.95,4.95c0.18,1.79 1.5,3.31 3.22,3.84c1.43,0.44 2.64,0.07 3.65,-0.51l2.5,2.5c0.39,0.39 1.01,0.39 1.4,0l0,0c0.39,-0.39 0.39,-1.01 0,-1.4L19.3,16.9zM15.5,17c-1.4,0 -2.5,-1.1 -2.5,-2.5s1.1,-2.5 2.5,-2.5s2.5,1.1 2.5,2.5S16.9,17 15.5,17zM12,20v2C6.48,22 2,17.52 2,12C2,6.48 6.48,2 12,2c4.84,0 8.87,3.44 9.8,8h-2.07c-0.64,-2.46 -2.4,-4.47 -4.73,-5.41V5c0,1.1 -0.9,2 -2,2h-2v2c0,0.55 -0.45,1 -1,1H8v2h2v3H9l-4.79,-4.79C4.08,10.79 4,11.38 4,12C4,16.41 7.59,20 12,20z"/>
</vector>

View File

@ -99,7 +99,7 @@
android:id="@+id/widget"
android:alpha="0"
android:gravity="center">
<include layout="@layout/the_widget_sans" />
<include layout="@layout/the_widget_sans" android:id="@+id/widget_detail" />
</LinearLayout>
<ProgressBar
android:layout_width="32dp"

View File

@ -72,7 +72,7 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change the text design"
android:text="Text font, size and color"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
@ -93,7 +93,7 @@
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_palette_24"
android:src="@drawable/round_dashboard_24"
app:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="0dp"
@ -106,7 +106,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/appearance_header"/>
android:text="Layout"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -114,10 +114,74 @@
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="8dp"
android:paddingRight="0dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:id="@+id/action_show_clock">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
app:tint="@color/colorPrimaryText"
android:src="@drawable/round_schedule_24"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_clock_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change the clock "
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/cardBorder"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:alpha="0.6" />
</LinearLayout>
<com.kyleduo.switchbutton.SwitchButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginStart="16dp"
app:kswThumbWidth="16sp"
app:kswThumbHeight="16sp"
app:kswBackRadius="16dp"
app:kswTintColor="@color/colorAccent"
android:checked="@{isClockVisible}"
android:id="@+id/show_clock_switch"
android:buttonTint="@color/colorAccent" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Content"
android:text="Smart content"
android:paddingTop="16dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
@ -251,70 +315,6 @@
android:id="@+id/show_weather_switch"
android:buttonTint="@color/colorAccent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="8dp"
android:paddingRight="0dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:id="@+id/action_show_clock">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
app:tint="@color/colorPrimaryText"
android:src="@drawable/round_schedule_24"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="@string/settings_clock_title"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change the clock "
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/cardBorder"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:alpha="0.6" />
</LinearLayout>
<com.kyleduo.switchbutton.SwitchButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginStart="16dp"
app:kswThumbWidth="16sp"
app:kswThumbHeight="16sp"
app:kswBackRadius="16dp"
app:kswTintColor="@color/colorAccent"
android:checked="@{isClockVisible}"
android:id="@+id/show_clock_switch"
android:buttonTint="@color/colorAccent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -379,6 +379,52 @@
android:id="@+id/show_glance_switch"
android:buttonTint="@color/colorAccent" />
</LinearLayout>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Gestures &amp; input"
android:paddingTop="16dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:textAppearance="@style/AnotherWidget.Settings.Header" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:id="@+id/action_tab_default_app"
android:orientation="horizontal">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_add_to_home_screen_24"
app:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/AnotherWidget.Settings.Title"
android:text="Gestures"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change the widget design"
style="@style/AnotherWidget.Settings.Subtitle"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.tommasoberlose.anotherwidget.components.FixedFocusScrollView>
</layout>

View File

@ -51,7 +51,7 @@
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/round_language_24"
android:src="@drawable/round_travel_explore_24"
app:tint="@color/colorPrimaryText"/>
<LinearLayout
android:layout_width="0dp"

View File

@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.4.10'
ext.kotlin_version = '1.4.21'
repositories {
google()
jcenter()