No issue: Use ImageView rather than rebuilding drawable (#3616)
HomeFragment's onboarding items included drawableStart values, but also built drawables in the view holders to replace them. Instead, we should just use ImageViews so that work isn't duplicated.master
parent
4994554576
commit
e8bd090a8e
|
@ -0,0 +1,11 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.ext
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
|
||||||
|
fun Drawable.setBounds(size: Int) {
|
||||||
|
setBounds(0, 0, size, size)
|
||||||
|
}
|
|
@ -88,7 +88,7 @@ class HomeFragment : Fragment(), AccountObserver {
|
||||||
private val singleSessionObserver = object : Session.Observer {
|
private val singleSessionObserver = object : Session.Observer {
|
||||||
override fun onTitleChanged(session: Session, title: String) {
|
override fun onTitleChanged(session: Session, title: String) {
|
||||||
super.onTitleChanged(session, title)
|
super.onTitleChanged(session, title)
|
||||||
if (deleteAllSessionsJob != null) { return }
|
if (deleteAllSessionsJob != null) return
|
||||||
emitSessionChanges()
|
emitSessionChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@ import org.mozilla.fenix.home.sessioncontrol.onNext
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class TabViewHolder(
|
class TabViewHolder(
|
||||||
val view: View,
|
view: View,
|
||||||
actionEmitter: Observer<SessionControlAction>,
|
actionEmitter: Observer<SessionControlAction>,
|
||||||
val job: Job,
|
private val job: Job,
|
||||||
override val containerView: View? = view
|
override val containerView: View? = view
|
||||||
) :
|
) :
|
||||||
RecyclerView.ViewHolder(view), LayoutContainer, CoroutineScope {
|
RecyclerView.ViewHolder(view), LayoutContainer, CoroutineScope {
|
||||||
|
|
|
@ -23,6 +23,7 @@ class OnboardingFinishViewHolder(
|
||||||
actionEmitter.onNext(OnboardingAction.Finish)
|
actionEmitter.onNext(OnboardingAction.Finish)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val LAYOUT_ID = R.layout.onboarding_finish
|
const val LAYOUT_ID = R.layout.onboarding_finish
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||||
|
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.setBounds
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the drawableStart of a header in an onboarding card.
|
||||||
|
*/
|
||||||
|
fun TextView.setOnboardingIcon(@DrawableRes id: Int) {
|
||||||
|
val icon = AppCompatResources.getDrawable(context, id)
|
||||||
|
val size = context.resources.getDimensionPixelSize(R.dimen.onboarding_header_icon_height_width)
|
||||||
|
icon?.setBounds(size)
|
||||||
|
|
||||||
|
setCompoundDrawablesRelative(icon, null, null, null)
|
||||||
|
}
|
|
@ -5,21 +5,15 @@
|
||||||
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlinx.android.synthetic.main.onboarding_privacy_notice.view.*
|
import kotlinx.android.synthetic.main.onboarding_privacy_notice.view.*
|
||||||
import org.jetbrains.anko.dimen
|
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.settings.SupportUtils
|
import org.mozilla.fenix.settings.SupportUtils
|
||||||
|
|
||||||
class OnboardingPrivacyNoticeViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
class OnboardingPrivacyNoticeViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val icon = AppCompatResources.getDrawable(view.context, R.drawable.ic_onboarding_privacy_notice)
|
view.header_text.setOnboardingIcon(R.drawable.ic_onboarding_privacy_notice)
|
||||||
val size = view.context.dimen(R.dimen.onboarding_header_icon_height_width)
|
|
||||||
icon?.setBounds(0, 0, size, size)
|
|
||||||
|
|
||||||
view.header_text.setCompoundDrawables(icon, null, null, null)
|
|
||||||
|
|
||||||
val appName = view.context.getString(R.string.app_name)
|
val appName = view.context.getString(R.string.app_name)
|
||||||
view.description_text.text = view.context.getString(R.string.onboarding_privacy_notice_description, appName)
|
view.description_text.text = view.context.getString(R.string.onboarding_privacy_notice_description, appName)
|
||||||
|
|
|
@ -4,24 +4,52 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.text.style.ImageSpan
|
import android.text.style.ImageSpan
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlinx.android.synthetic.main.onboarding_private_browsing.view.*
|
import kotlinx.android.synthetic.main.onboarding_private_browsing.view.*
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.ext.setBounds
|
||||||
|
|
||||||
class OnboardingPrivateBrowsingViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
class OnboardingPrivateBrowsingViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val iconDrawable = AppCompatResources.getDrawable(view.context, R.drawable.ic_private_browsing)!!
|
view.header_text.setOnboardingIcon(R.drawable.ic_onboarding_private_browsing)
|
||||||
iconDrawable.setBounds(0, 0, view.description_text.lineHeight, view.description_text.lineHeight)
|
|
||||||
|
|
||||||
val icon = object : ImageSpan(iconDrawable) {
|
// Display a private browsing icon as a character inside the description text.
|
||||||
|
val inlineIcon = PrivateBrowsingImageSpan(
|
||||||
|
view.context,
|
||||||
|
R.drawable.ic_private_browsing,
|
||||||
|
view.description_text.lineHeight
|
||||||
|
)
|
||||||
|
|
||||||
|
val text = SpannableString(view.context.getString(R.string.onboarding_private_browsing_description)).apply {
|
||||||
|
val spanStartIndex = indexOf(IMAGE_PLACEHOLDER)
|
||||||
|
setSpan(
|
||||||
|
inlineIcon,
|
||||||
|
spanStartIndex,
|
||||||
|
spanStartIndex + IMAGE_PLACEHOLDER.length,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
view.description_text.text = text
|
||||||
|
}
|
||||||
|
|
||||||
|
class PrivateBrowsingImageSpan(
|
||||||
|
context: Context,
|
||||||
|
@DrawableRes drawableId: Int,
|
||||||
|
size: Int
|
||||||
|
) : ImageSpan(
|
||||||
|
AppCompatResources.getDrawable(context, drawableId)!!.apply { setBounds(size) }
|
||||||
|
) {
|
||||||
override fun draw(
|
override fun draw(
|
||||||
canvas: Canvas,
|
canvas: Canvas,
|
||||||
text: CharSequence?,
|
text: CharSequence?,
|
||||||
|
@ -44,19 +72,6 @@ class OnboardingPrivateBrowsingViewHolder(view: View) : RecyclerView.ViewHolder(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val text = SpannableString(view.context.getString(R.string.onboarding_private_browsing_description))
|
|
||||||
val spanStartIndex = text.indexOf(IMAGE_PLACEHOLDER)
|
|
||||||
|
|
||||||
text.setSpan(
|
|
||||||
icon,
|
|
||||||
spanStartIndex,
|
|
||||||
spanStartIndex + IMAGE_PLACEHOLDER.length,
|
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
|
||||||
)
|
|
||||||
|
|
||||||
view.description_text.text = text
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val IMAGE_PLACEHOLDER = "%s"
|
const val IMAGE_PLACEHOLDER = "%s"
|
||||||
const val LAYOUT_ID = R.layout.onboarding_private_browsing
|
const val LAYOUT_ID = R.layout.onboarding_private_browsing
|
||||||
|
|
|
@ -4,37 +4,27 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Build.VERSION.SDK_INT
|
import android.os.Build.VERSION.SDK_INT
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlinx.android.synthetic.main.onboarding_section_header.view.*
|
|
||||||
import kotlinx.android.synthetic.main.onboarding_theme_picker.view.*
|
import kotlinx.android.synthetic.main.onboarding_theme_picker.view.*
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
class OnboardingThemePickerViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
|
class OnboardingThemePickerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
|
||||||
fun bind(labelBuilder: (Context) -> String) {
|
|
||||||
view.section_header_text.text = labelBuilder(view.context)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val LAYOUT_ID = R.layout.onboarding_theme_picker
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val radioLightTheme = view.theme_light_radio_button
|
val radioLightTheme = view.theme_light_radio_button
|
||||||
val radioDarkTheme = view.theme_dark_radio_button
|
val radioDarkTheme = view.theme_dark_radio_button
|
||||||
val radioFollowDeviceTheme = view.theme_automatic_radio_button
|
val radioFollowDeviceTheme = view.theme_automatic_radio_button
|
||||||
|
|
||||||
if (SDK_INT >= Build.VERSION_CODES.P) {
|
radioFollowDeviceTheme.key = if (SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
radioFollowDeviceTheme?.key = R.string.pref_key_follow_device_theme
|
R.string.pref_key_follow_device_theme
|
||||||
} else {
|
} else {
|
||||||
radioFollowDeviceTheme?.key = R.string.pref_key_auto_battery_theme
|
R.string.pref_key_auto_battery_theme
|
||||||
}
|
}
|
||||||
|
|
||||||
radioLightTheme.addToRadioGroup(radioDarkTheme)
|
radioLightTheme.addToRadioGroup(radioDarkTheme)
|
||||||
|
@ -79,20 +69,25 @@ class OnboardingThemePickerViewHolder(private val view: View) : RecyclerView.Vie
|
||||||
}
|
}
|
||||||
|
|
||||||
with(Settings.getInstance(view.context)) {
|
with(Settings.getInstance(view.context)) {
|
||||||
when {
|
val radio = when {
|
||||||
this.shouldUseLightTheme -> radioLightTheme.isChecked = true
|
this.shouldUseLightTheme -> radioLightTheme
|
||||||
this.shouldUseDarkTheme -> radioDarkTheme.isChecked = true
|
this.shouldUseDarkTheme -> radioDarkTheme
|
||||||
else -> radioFollowDeviceTheme.isChecked = true
|
else -> radioFollowDeviceTheme
|
||||||
}
|
}
|
||||||
|
radio.isChecked = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setNewTheme(mode: Int) {
|
private fun setNewTheme(mode: Int) {
|
||||||
if (AppCompatDelegate.getDefaultNightMode() == mode) return
|
if (AppCompatDelegate.getDefaultNightMode() == mode) return
|
||||||
AppCompatDelegate.setDefaultNightMode(mode)
|
AppCompatDelegate.setDefaultNightMode(mode)
|
||||||
view.context?.components?.core?.let {
|
with(itemView.context.components) {
|
||||||
it.engine.settings.preferredColorScheme = it.getPreferredColorScheme()
|
core.engine.settings.preferredColorScheme = core.getPreferredColorScheme()
|
||||||
|
useCases.sessionUseCases.reload.invoke()
|
||||||
}
|
}
|
||||||
view.context?.components?.useCases?.sessionUseCases?.reload?.invoke()
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val LAYOUT_ID = R.layout.onboarding_theme_picker
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,22 +5,16 @@
|
||||||
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import kotlinx.android.synthetic.main.onboarding_tracking_protection.view.*
|
import kotlinx.android.synthetic.main.onboarding_tracking_protection.view.*
|
||||||
import org.jetbrains.anko.dimen
|
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
class OnboardingTrackingProtectionViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
class OnboardingTrackingProtectionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val icon = AppCompatResources.getDrawable(view.context, R.drawable.ic_onboarding_tracking_protection)
|
view.header_text.setOnboardingIcon(R.drawable.ic_onboarding_tracking_protection)
|
||||||
val size = view.context.dimen(R.dimen.onboarding_header_icon_height_width)
|
|
||||||
icon?.setBounds(0, 0, size, size)
|
|
||||||
|
|
||||||
view.header_text.setCompoundDrawables(icon, null, null, null)
|
|
||||||
|
|
||||||
val appName = view.context.getString(R.string.app_name)
|
val appName = view.context.getString(R.string.app_name)
|
||||||
view.description_text.text = view.context.getString(
|
view.description_text.text = view.context.getString(
|
||||||
|
@ -28,24 +22,21 @@ class OnboardingTrackingProtectionViewHolder(val view: View) : RecyclerView.View
|
||||||
appName
|
appName
|
||||||
)
|
)
|
||||||
|
|
||||||
val switch = view.tracking_protection_toggle
|
view.tracking_protection_toggle.apply {
|
||||||
|
isChecked = Settings.getInstance(view.context).shouldUseTrackingProtection
|
||||||
switch.isChecked = Settings.getInstance(view.context).shouldUseTrackingProtection
|
setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
|
||||||
switch.setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
updateTrackingProtectionSetting(isChecked)
|
updateTrackingProtectionSetting(isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateTrackingProtectionSetting(enabled: Boolean) {
|
private fun updateTrackingProtectionSetting(enabled: Boolean) {
|
||||||
Settings.getInstance(view.context).setTrackingProtection(enabled)
|
Settings.getInstance(itemView.context).setTrackingProtection(enabled)
|
||||||
with(view.context.components) {
|
with(itemView.context.components) {
|
||||||
val policy = core.createTrackingProtectionPolicy(enabled)
|
val policy = core.createTrackingProtectionPolicy(enabled)
|
||||||
useCases.settingsUseCases.updateTrackingProtection.invoke(policy)
|
useCases.settingsUseCases.updateTrackingProtection.invoke(policy)
|
||||||
useCases.sessionUseCases.reload.invoke()
|
useCases.sessionUseCases.reload.invoke()
|
||||||
}
|
}
|
||||||
|
|
||||||
view.context.components.useCases.sessionUseCases.reload.invoke()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -6,34 +6,32 @@ package org.mozilla.fenix.onboarding
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import androidx.core.content.edit
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
|
|
||||||
class FenixOnboarding(private val context: Context) {
|
class FenixOnboarding(context: Context) {
|
||||||
private val onboardingPrefs = context.applicationContext.getSharedPreferences(
|
private val metrics = context.components.analytics.metrics
|
||||||
OnboardingKeys.PREF_NAME.key,
|
private val onboardingPrefs = context.getSharedPreferences(
|
||||||
|
PREF_NAME_ONBOARDING_KEY,
|
||||||
Context.MODE_PRIVATE
|
Context.MODE_PRIVATE
|
||||||
)
|
)
|
||||||
|
|
||||||
private var SharedPreferences.onboardedVersion: Int
|
private var SharedPreferences.onboardedVersion: Int
|
||||||
get() = getInt(OnboardingKeys.LAST_VERSION.key, 0)
|
get() = getInt(LAST_VERSION_ONBOARDING_KEY, 0)
|
||||||
set(version) { edit().putInt(OnboardingKeys.LAST_VERSION.key, version).apply() }
|
set(version) { edit { putInt(LAST_VERSION_ONBOARDING_KEY, version) } }
|
||||||
|
|
||||||
fun finish() {
|
fun finish() {
|
||||||
onboardingPrefs.onboardedVersion = CURRENT_ONBOARDING_VERSION
|
onboardingPrefs.onboardedVersion = CURRENT_ONBOARDING_VERSION
|
||||||
context.components.analytics.metrics.track(Event.DismissedOnboarding)
|
metrics.track(Event.DismissedOnboarding)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun userHasBeenOnboarded(): Boolean {
|
fun userHasBeenOnboarded() = onboardingPrefs.onboardedVersion == CURRENT_ONBOARDING_VERSION
|
||||||
return onboardingPrefs.onboardedVersion == CURRENT_ONBOARDING_VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum class OnboardingKeys(val key: String) {
|
|
||||||
PREF_NAME("fenix.onboarding"),
|
|
||||||
LAST_VERSION("fenix.onboarding.last_version")
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val CURRENT_ONBOARDING_VERSION = 1
|
private const val CURRENT_ONBOARDING_VERSION = 1
|
||||||
|
|
||||||
|
private const val PREF_NAME_ONBOARDING_KEY = "fenix.onboarding"
|
||||||
|
private const val LAST_VERSION_ONBOARDING_KEY = "fenix.onboarding.last_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ package org.mozilla.fenix.onboarding
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import androidx.appcompat.widget.AppCompatRadioButton
|
import androidx.appcompat.widget.AppCompatRadioButton
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import androidx.core.content.withStyledAttributes
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.utils.Settings
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
|
@ -16,20 +18,12 @@ class OnboardingRadioButton(context: Context, attrs: AttributeSet) : AppCompatRa
|
||||||
var key: Int = 0
|
var key: Int = 0
|
||||||
|
|
||||||
init {
|
init {
|
||||||
attrs.let {
|
context.withStyledAttributes(
|
||||||
context.theme.obtainStyledAttributes(
|
attrs,
|
||||||
it,
|
|
||||||
R.styleable.OnboardingRadioButton,
|
R.styleable.OnboardingRadioButton,
|
||||||
0, 0
|
0, 0
|
||||||
).apply {
|
) {
|
||||||
try {
|
key = getResourceId(R.styleable.OnboardingRadioButton_onboardingKey, 0)
|
||||||
key = getResourceId(
|
|
||||||
R.styleable.OnboardingRadioButton_onboardingKey, 0
|
|
||||||
)
|
|
||||||
} finally {
|
|
||||||
recycle()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +31,7 @@ class OnboardingRadioButton(context: Context, attrs: AttributeSet) : AppCompatRa
|
||||||
radioGroups.add(radioButton)
|
radioGroups.add(radioButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onClickListener(listener: (() -> Unit)) {
|
fun onClickListener(listener: () -> Unit) {
|
||||||
clickListener = listener
|
clickListener = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +45,13 @@ class OnboardingRadioButton(context: Context, attrs: AttributeSet) : AppCompatRa
|
||||||
|
|
||||||
private fun updateRadioValue(isChecked: Boolean) {
|
private fun updateRadioValue(isChecked: Boolean) {
|
||||||
this.isChecked = isChecked
|
this.isChecked = isChecked
|
||||||
Settings.getInstance(context).preferences.edit().putBoolean(context.getString(key), isChecked)
|
Settings.getInstance(context).preferences.edit {
|
||||||
.apply()
|
putBoolean(context.getString(key), isChecked)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toggleRadioGroups() {
|
private fun toggleRadioGroups() {
|
||||||
if (this.isChecked) {
|
if (isChecked) {
|
||||||
radioGroups.forEach { it.updateRadioValue(false) }
|
radioGroups.forEach { it.updateRadioValue(false) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/onboarding_card"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
style="@style/OnboardingCardDark"
|
style="@style/OnboardingCardDark"
|
||||||
|
android:id="@+id/onboarding_card"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
@ -15,9 +17,9 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="14dp"
|
android:layout_marginBottom="14dp"
|
||||||
app:drawableStartCompat="@drawable/ic_onboarding_firefox_accounts"
|
tools:text="@string/onboarding_firefox_account_header"
|
||||||
|
tools:drawableStart="@drawable/ic_onboarding_firefox_accounts"
|
||||||
android:drawablePadding="12dp"
|
android:drawablePadding="12dp"
|
||||||
android:text="@string/onboarding_firefox_account_header"
|
|
||||||
android:textAppearance="@style/Header16TextStyle"
|
android:textAppearance="@style/Header16TextStyle"
|
||||||
android:textColor="@color/onboarding_card_primary_text_dark" />
|
android:textColor="@color/onboarding_card_primary_text_dark" />
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/onboarding_header"
|
android:id="@+id/onboarding_header"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -12,7 +13,7 @@
|
||||||
android:id="@+id/header_text"
|
android:id="@+id/header_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/onboarding_header"
|
tools:text="@string/onboarding_header"
|
||||||
android:textAppearance="@style/HeaderTextStyle"
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
android:textSize="22sp" />
|
android:textSize="22sp" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
|
@ -2,29 +2,37 @@
|
||||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<LinearLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/onboarding_card"
|
android:id="@+id/onboarding_card"
|
||||||
style="@style/OnboardingCardLight"
|
style="@style/OnboardingCardLight"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/header_text"
|
android:id="@+id/header_text"
|
||||||
app:drawableStartCompat="@drawable/ic_onboarding_privacy_notice"
|
android:layout_width="0dp"
|
||||||
android:drawablePadding="12dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="14dp"
|
|
||||||
android:text="@string/onboarding_privacy_notice_header"
|
android:text="@string/onboarding_privacy_notice_header"
|
||||||
android:textAppearance="@style/HeaderTextStyle" />
|
tools:drawableStart="@drawable/ic_onboarding_privacy_notice"
|
||||||
|
android:drawablePadding="12dp"
|
||||||
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:lines="1"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/description_text"
|
android:id="@+id/description_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/onboarding_privacy_notice_description"
|
android:textAppearance="@style/Body14TextStyle"
|
||||||
android:textAppearance="@style/Body14TextStyle" />
|
android:layout_marginTop="14dp"
|
||||||
|
tools:text="@string/onboarding_privacy_notice_description"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/header_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/read_button"
|
android:id="@+id/read_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -35,7 +43,11 @@
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:foreground="?android:attr/selectableItemBackground"
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
android:padding="10dp">
|
android:padding="10dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/description_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -48,4 +60,4 @@
|
||||||
android:textColor="?primaryText"
|
android:textColor="?primaryText"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -2,42 +2,35 @@
|
||||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/onboarding_card"
|
android:id="@+id/onboarding_card"
|
||||||
style="@style/OnboardingCardLight"
|
style="@style/OnboardingCardLight"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
<ImageView
|
|
||||||
android:importantForAccessibility="no"
|
|
||||||
android:id="@+id/private_browsing_icon"
|
|
||||||
android:layout_width="30dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
app:layout_constraintDimensionRatio="H,1:1"
|
|
||||||
app:srcCompat="@drawable/ic_onboarding_private_browsing"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/header_text"
|
android:id="@+id/header_text"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
|
tools:drawableStart="@drawable/ic_onboarding_private_browsing"
|
||||||
|
android:drawablePadding="12dp"
|
||||||
android:text="@string/onboarding_private_browsing_header"
|
android:text="@string/onboarding_private_browsing_header"
|
||||||
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:lines="1"
|
android:lines="1"
|
||||||
android:textAppearance="@style/HeaderTextStyle"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:layout_marginStart="12dp"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/private_browsing_icon"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/private_browsing_icon"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/private_browsing_icon"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/description_text"
|
android:id="@+id/description_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/onboarding_private_browsing_description"
|
|
||||||
android:textAppearance="@style/Body14TextStyle"
|
android:textAppearance="@style/Body14TextStyle"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_marginTop="14dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/private_browsing_icon"
|
tools:text="@string/onboarding_private_browsing_description"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/header_text"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent" />
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
|
@ -2,15 +2,12 @@
|
||||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<FrameLayout
|
<TextView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/onboarding_header"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="16dp">
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/section_header_text"
|
android:id="@+id/section_header_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/HeaderTextStyle" tools:text="@tools:sample/lorem"/>
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
</FrameLayout>
|
tools:text="@tools:sample/lorem"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
|
@ -2,38 +2,43 @@
|
||||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/onboarding_card"
|
android:id="@+id/onboarding_card"
|
||||||
style="@style/OnboardingCardLight"
|
style="@style/OnboardingCardLight"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/header_text"
|
android:id="@+id/header_text"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:drawableStartCompat="@drawable/ic_onboarding_tracking_protection"
|
|
||||||
android:drawablePadding="12dp"
|
|
||||||
android:text="@string/onboarding_tracking_protection_header"
|
android:text="@string/onboarding_tracking_protection_header"
|
||||||
|
tools:drawableStart="@drawable/ic_onboarding_tracking_protection"
|
||||||
|
android:drawablePadding="12dp"
|
||||||
android:textAppearance="@style/HeaderTextStyle"
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
android:gravity="center_vertical"
|
||||||
|
android:lines="1"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@id/tracking_protection_toggle"/>
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/tracking_protection_toggle" />
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/tracking_protection_toggle"
|
android:id="@+id/tracking_protection_toggle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="@id/header_text"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/header_text"/>
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/description_text"
|
android:id="@+id/description_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/onboarding_tracking_protection_description"
|
|
||||||
android:textAppearance="@style/Body14TextStyle"
|
android:textAppearance="@style/Body14TextStyle"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
tools:text="@string/onboarding_tracking_protection_description"
|
||||||
app:layout_constraintTop_toBottomOf="@id/header_text"
|
app:layout_constraintTop_toBottomOf="@id/header_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/private_session_description_wrapper"
|
android:id="@+id/private_session_description_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
android:textColor="?primaryText"
|
android:textColor="?primaryText"
|
||||||
android:text="@string/private_browsing_title"
|
android:text="@string/private_browsing_title"
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
android:ellipsize="none"
|
android:ellipsize="none"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:scrollHorizontally="false"
|
android:scrollHorizontally="false"
|
||||||
android:text="@string/private_browsing_explanation"
|
tools:text="@string/private_browsing_explanation"
|
||||||
android:textColor="?primaryText"
|
android:textColor="?primaryText"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
Loading…
Reference in New Issue