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
|
@ -45,7 +45,7 @@ fun Context.getPreferenceKey(@StringRes resourceId: Int): String =
|
||||||
resources.getString(resourceId)
|
resources.getString(resourceId)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shares content via [ACTION_SEND] intent.
|
* Shares content via [ACTION_SEND] intent.
|
||||||
*
|
*
|
||||||
* @param text the data to be shared [EXTRA_TEXT]
|
* @param text the data to be shared [EXTRA_TEXT]
|
||||||
* @param subject of the intent [EXTRA_TEXT]
|
* @param subject of the intent [EXTRA_TEXT]
|
||||||
|
@ -74,7 +74,7 @@ fun Context.share(text: String, subject: String = ""): Boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Root View with an activity context
|
* Gets the Root View with an activity context
|
||||||
*
|
*
|
||||||
* @return ViewGroup? if it is able to get a root view from the context
|
* @return ViewGroup? if it is able to get a root view from the context
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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,59 +4,74 @@
|
||||||
|
|
||||||
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.
|
||||||
override fun draw(
|
val inlineIcon = PrivateBrowsingImageSpan(
|
||||||
canvas: Canvas,
|
view.context,
|
||||||
text: CharSequence?,
|
R.drawable.ic_private_browsing,
|
||||||
start: Int,
|
view.description_text.lineHeight
|
||||||
end: Int,
|
|
||||||
x: Float,
|
|
||||||
top: Int,
|
|
||||||
y: Int,
|
|
||||||
bottom: Int,
|
|
||||||
paint: Paint
|
|
||||||
) {
|
|
||||||
canvas.save()
|
|
||||||
val fmPaint = paint.fontMetricsInt
|
|
||||||
val fontHeight = fmPaint.descent - fmPaint.ascent
|
|
||||||
val centerY = y + fmPaint.descent - fontHeight / 2
|
|
||||||
val transY = (centerY - (drawable.bounds.bottom - drawable.bounds.top) / 2).toFloat()
|
|
||||||
canvas.translate(x, transY)
|
|
||||||
drawable.draw(canvas)
|
|
||||||
canvas.restore()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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
|
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(
|
||||||
|
canvas: Canvas,
|
||||||
|
text: CharSequence?,
|
||||||
|
start: Int,
|
||||||
|
end: Int,
|
||||||
|
x: Float,
|
||||||
|
top: Int,
|
||||||
|
y: Int,
|
||||||
|
bottom: Int,
|
||||||
|
paint: Paint
|
||||||
|
) {
|
||||||
|
canvas.save()
|
||||||
|
val fmPaint = paint.fontMetricsInt
|
||||||
|
val fontHeight = fmPaint.descent - fmPaint.ascent
|
||||||
|
val centerY = y + fmPaint.descent - fontHeight / 2
|
||||||
|
val transY = (centerY - (drawable.bounds.bottom - drawable.bounds.top) / 2).toFloat()
|
||||||
|
canvas.translate(x, transY)
|
||||||
|
drawable.draw(canvas)
|
||||||
|
canvas.restore()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 ->
|
||||||
|
updateTrackingProtectionSetting(isChecked)
|
||||||
switch.setOnCheckedChangeListener { _, 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 {
|
key = getResourceId(R.styleable.OnboardingRadioButton_onboardingKey, 0)
|
||||||
try {
|
|
||||||
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,22 +2,24 @@
|
||||||
<!-- 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:app="http://schemas.android.com/apk/res-auto"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/onboarding_card"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
style="@style/OnboardingCardDark"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
style="@style/OnboardingCardDark"
|
||||||
android:layout_height="wrap_content"
|
android:id="@+id/onboarding_card"
|
||||||
android:orientation="vertical">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
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: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" />
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,17 @@
|
||||||
- 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
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/onboarding_header"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/onboarding_header"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="8dp">
|
|
||||||
<TextView
|
|
||||||
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"
|
android:layout_marginBottom="8dp">
|
||||||
android:textAppearance="@style/HeaderTextStyle"
|
<TextView
|
||||||
android:textSize="22sp" />
|
android:id="@+id/header_text"
|
||||||
</FrameLayout>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="@string/onboarding_header"
|
||||||
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
|
android:textSize="22sp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
|
@ -2,50 +2,62 @@
|
||||||
<!-- 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"
|
||||||
android:id="@+id/onboarding_card"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
style="@style/OnboardingCardLight"
|
android:id="@+id/onboarding_card"
|
||||||
android:layout_width="match_parent"
|
style="@style/OnboardingCardLight"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:orientation="vertical">
|
android:layout_height="wrap_content">
|
||||||
<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_marginBottom="14dp"
|
|
||||||
android:text="@string/onboarding_privacy_notice_header"
|
|
||||||
android:textAppearance="@style/HeaderTextStyle" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/description_text"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/onboarding_privacy_notice_description"
|
|
||||||
android:textAppearance="@style/Body14TextStyle" />
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/read_button"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:background="@drawable/button_background"
|
|
||||||
android:backgroundTint="?neutralFaded"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:foreground="?android:attr/selectableItemBackground"
|
|
||||||
android:padding="10dp">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:text="@string/onboarding_privacy_notice_header"
|
||||||
android:clickable="false"
|
tools:drawableStart="@drawable/ic_onboarding_privacy_notice"
|
||||||
android:focusable="false"
|
android:drawablePadding="12dp"
|
||||||
android:textStyle="bold"
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
android:gravity="center"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/onboarding_privacy_notice_read_button"
|
android:lines="1"
|
||||||
android:textColor="?primaryText"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
android:textSize="14sp" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/description_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
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
|
||||||
|
android:id="@+id/read_button"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@drawable/button_background"
|
||||||
|
android:backgroundTint="?neutralFaded"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
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
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:clickable="false"
|
||||||
|
android:focusable="false"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/onboarding_privacy_notice_read_button"
|
||||||
|
android:textColor="?primaryText"
|
||||||
|
android:textSize="14sp" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -2,43 +2,36 @@
|
||||||
<!-- 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:app="http://schemas.android.com/apk/res-auto"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/onboarding_card"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
style="@style/OnboardingCardLight"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/onboarding_card"
|
||||||
android:layout_height="wrap_content">
|
style="@style/OnboardingCardLight"
|
||||||
<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
|
|
||||||
android:id="@+id/header_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:text="@string/onboarding_private_browsing_header"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:lines="1"
|
|
||||||
android:textAppearance="@style/HeaderTextStyle"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
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" />
|
|
||||||
<TextView
|
|
||||||
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"
|
<TextView
|
||||||
android:textAppearance="@style/Body14TextStyle"
|
android:id="@+id/header_text"
|
||||||
android:layout_marginTop="14dp"
|
android:layout_width="0dp"
|
||||||
app:layout_constraintTop_toBottomOf="@id/private_browsing_icon"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
tools:drawableStart="@drawable/ic_onboarding_private_browsing"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:drawablePadding="12dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent" />
|
android:text="@string/onboarding_private_browsing_header"
|
||||||
|
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
|
||||||
|
android:id="@+id/description_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/Body14TextStyle"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
tools:text="@string/onboarding_private_browsing_description"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/header_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -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:id="@+id/section_header_text"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginBottom="16dp">
|
android:layout_height="wrap_content"
|
||||||
<TextView
|
android:textAppearance="@style/HeaderTextStyle"
|
||||||
android:id="@+id/section_header_text"
|
tools:text="@tools:sample/lorem"
|
||||||
android:layout_width="match_parent"
|
android:layout_marginBottom="16dp" />
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="@style/HeaderTextStyle" tools:text="@tools:sample/lorem"/>
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
|
@ -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:app="http://schemas.android.com/apk/res-auto"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/onboarding_card"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
style="@style/OnboardingCardLight"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/onboarding_card"
|
||||||
android:layout_height="wrap_content"
|
style="@style/OnboardingCardLight"
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/header_text"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:drawableStartCompat="@drawable/ic_onboarding_tracking_protection"
|
|
||||||
android:drawablePadding="12dp"
|
|
||||||
android:text="@string/onboarding_tracking_protection_header"
|
|
||||||
android:textAppearance="@style/HeaderTextStyle"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/tracking_protection_toggle"/>
|
|
||||||
<Switch
|
|
||||||
android:id="@+id/tracking_protection_toggle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
<TextView
|
|
||||||
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"
|
<TextView
|
||||||
android:textAppearance="@style/Body14TextStyle"
|
android:id="@+id/header_text"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_width="0dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintTop_toBottomOf="@id/header_text"
|
android:text="@string/onboarding_tracking_protection_header"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
tools:drawableStart="@drawable/ic_onboarding_tracking_protection"
|
||||||
|
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_toStartOf="@id/tracking_protection_toggle" />
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/tracking_protection_toggle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/header_text"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/header_text"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/description_text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/Body14TextStyle"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
tools:text="@string/onboarding_tracking_protection_description"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/header_text"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -3,27 +3,27 @@
|
||||||
- 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_height="wrap_content"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
|
||||||
android:textColor="?primaryText"
|
|
||||||
android:text="@string/private_browsing_title"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/private_session_description"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ellipsize="none"
|
android:layout_margin="16dp"
|
||||||
android:gravity="center_vertical"
|
android:orientation="vertical">
|
||||||
android:scrollHorizontally="false"
|
<TextView
|
||||||
android:text="@string/private_browsing_explanation"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
android:textColor="?primaryText"
|
android:textColor="?primaryText"
|
||||||
android:textSize="14sp" />
|
android:text="@string/private_browsing_title"
|
||||||
</LinearLayout>
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/private_session_description"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="none"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:scrollHorizontally="false"
|
||||||
|
tools:text="@string/private_browsing_explanation"
|
||||||
|
android:textColor="?primaryText"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
Loading…
Reference in New Issue