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.
nightly-build-test
Tiger Oakes 5 years ago committed by Sawyer Blatz
parent 4994554576
commit e8bd090a8e

@ -45,7 +45,7 @@ fun Context.getPreferenceKey(@StringRes resourceId: Int): String =
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 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
*/

@ -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 {
override fun onTitleChanged(session: Session, title: String) {
super.onTitleChanged(session, title)
if (deleteAllSessionsJob != null) { return }
if (deleteAllSessionsJob != null) return
emitSessionChanges()
}
}

@ -30,9 +30,9 @@ import org.mozilla.fenix.home.sessioncontrol.onNext
import kotlin.coroutines.CoroutineContext
class TabViewHolder(
val view: View,
view: View,
actionEmitter: Observer<SessionControlAction>,
val job: Job,
private val job: Job,
override val containerView: View? = view
) :
RecyclerView.ViewHolder(view), LayoutContainer, CoroutineScope {

@ -23,6 +23,7 @@ class OnboardingFinishViewHolder(
actionEmitter.onNext(OnboardingAction.Finish)
}
}
companion object {
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
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_privacy_notice.view.*
import org.jetbrains.anko.dimen
import org.mozilla.fenix.R
import org.mozilla.fenix.settings.SupportUtils
class OnboardingPrivacyNoticeViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
val icon = AppCompatResources.getDrawable(view.context, 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)
view.header_text.setOnboardingIcon(R.drawable.ic_onboarding_privacy_notice)
val appName = view.context.getString(R.string.app_name)
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
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ImageSpan
import android.view.View
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_private_browsing.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.setBounds
class OnboardingPrivateBrowsingViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
val iconDrawable = AppCompatResources.getDrawable(view.context, R.drawable.ic_private_browsing)!!
iconDrawable.setBounds(0, 0, view.description_text.lineHeight, view.description_text.lineHeight)
view.header_text.setOnboardingIcon(R.drawable.ic_onboarding_private_browsing)
val icon = object : ImageSpan(iconDrawable) {
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()
}
}
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
// 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(
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 {
const val IMAGE_PLACEHOLDER = "%s"
const val LAYOUT_ID = R.layout.onboarding_private_browsing

@ -4,37 +4,27 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
import android.content.Context
import android.os.Build
import android.os.Build.VERSION.SDK_INT
import android.view.View
import androidx.appcompat.app.AppCompatDelegate
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_section_header.view.*
import kotlinx.android.synthetic.main.onboarding_theme_picker.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.utils.Settings
class OnboardingThemePickerViewHolder(private val 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
}
class OnboardingThemePickerViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
val radioLightTheme = view.theme_light_radio_button
val radioDarkTheme = view.theme_dark_radio_button
val radioFollowDeviceTheme = view.theme_automatic_radio_button
if (SDK_INT >= Build.VERSION_CODES.P) {
radioFollowDeviceTheme?.key = R.string.pref_key_follow_device_theme
radioFollowDeviceTheme.key = if (SDK_INT >= Build.VERSION_CODES.P) {
R.string.pref_key_follow_device_theme
} else {
radioFollowDeviceTheme?.key = R.string.pref_key_auto_battery_theme
R.string.pref_key_auto_battery_theme
}
radioLightTheme.addToRadioGroup(radioDarkTheme)
@ -79,20 +69,25 @@ class OnboardingThemePickerViewHolder(private val view: View) : RecyclerView.Vie
}
with(Settings.getInstance(view.context)) {
when {
this.shouldUseLightTheme -> radioLightTheme.isChecked = true
this.shouldUseDarkTheme -> radioDarkTheme.isChecked = true
else -> radioFollowDeviceTheme.isChecked = true
val radio = when {
this.shouldUseLightTheme -> radioLightTheme
this.shouldUseDarkTheme -> radioDarkTheme
else -> radioFollowDeviceTheme
}
radio.isChecked = true
}
}
private fun setNewTheme(mode: Int) {
if (AppCompatDelegate.getDefaultNightMode() == mode) return
AppCompatDelegate.setDefaultNightMode(mode)
view.context?.components?.core?.let {
it.engine.settings.preferredColorScheme = it.getPreferredColorScheme()
with(itemView.context.components) {
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
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_tracking_protection.view.*
import org.jetbrains.anko.dimen
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.utils.Settings
class OnboardingTrackingProtectionViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
class OnboardingTrackingProtectionViewHolder(view: View) : RecyclerView.ViewHolder(view) {
init {
val icon = AppCompatResources.getDrawable(view.context, 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)
view.header_text.setOnboardingIcon(R.drawable.ic_onboarding_tracking_protection)
val appName = view.context.getString(R.string.app_name)
view.description_text.text = view.context.getString(
@ -28,24 +22,21 @@ class OnboardingTrackingProtectionViewHolder(val view: View) : RecyclerView.View
appName
)
val switch = view.tracking_protection_toggle
switch.isChecked = Settings.getInstance(view.context).shouldUseTrackingProtection
switch.setOnCheckedChangeListener { _, isChecked ->
updateTrackingProtectionSetting(isChecked)
view.tracking_protection_toggle.apply {
isChecked = Settings.getInstance(view.context).shouldUseTrackingProtection
setOnCheckedChangeListener { _, isChecked ->
updateTrackingProtectionSetting(isChecked)
}
}
}
private fun updateTrackingProtectionSetting(enabled: Boolean) {
Settings.getInstance(view.context).setTrackingProtection(enabled)
with(view.context.components) {
Settings.getInstance(itemView.context).setTrackingProtection(enabled)
with(itemView.context.components) {
val policy = core.createTrackingProtectionPolicy(enabled)
useCases.settingsUseCases.updateTrackingProtection.invoke(policy)
useCases.sessionUseCases.reload.invoke()
}
view.context.components.useCases.sessionUseCases.reload.invoke()
}
companion object {

@ -6,34 +6,32 @@ package org.mozilla.fenix.onboarding
import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
class FenixOnboarding(private val context: Context) {
private val onboardingPrefs = context.applicationContext.getSharedPreferences(
OnboardingKeys.PREF_NAME.key,
class FenixOnboarding(context: Context) {
private val metrics = context.components.analytics.metrics
private val onboardingPrefs = context.getSharedPreferences(
PREF_NAME_ONBOARDING_KEY,
Context.MODE_PRIVATE
)
private var SharedPreferences.onboardedVersion: Int
get() = getInt(OnboardingKeys.LAST_VERSION.key, 0)
set(version) { edit().putInt(OnboardingKeys.LAST_VERSION.key, version).apply() }
get() = getInt(LAST_VERSION_ONBOARDING_KEY, 0)
set(version) { edit { putInt(LAST_VERSION_ONBOARDING_KEY, version) } }
fun finish() {
onboardingPrefs.onboardedVersion = CURRENT_ONBOARDING_VERSION
context.components.analytics.metrics.track(Event.DismissedOnboarding)
metrics.track(Event.DismissedOnboarding)
}
fun userHasBeenOnboarded(): Boolean {
return onboardingPrefs.onboardedVersion == CURRENT_ONBOARDING_VERSION
}
private enum class OnboardingKeys(val key: String) {
PREF_NAME("fenix.onboarding"),
LAST_VERSION("fenix.onboarding.last_version")
}
fun userHasBeenOnboarded() = onboardingPrefs.onboardedVersion == CURRENT_ONBOARDING_VERSION
companion object {
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.util.AttributeSet
import androidx.appcompat.widget.AppCompatRadioButton
import androidx.core.content.edit
import androidx.core.content.withStyledAttributes
import org.mozilla.fenix.R
import org.mozilla.fenix.utils.Settings
@ -16,20 +18,12 @@ class OnboardingRadioButton(context: Context, attrs: AttributeSet) : AppCompatRa
var key: Int = 0
init {
attrs.let {
context.theme.obtainStyledAttributes(
it,
R.styleable.OnboardingRadioButton,
0, 0
).apply {
try {
key = getResourceId(
R.styleable.OnboardingRadioButton_onboardingKey, 0
)
} finally {
recycle()
}
}
context.withStyledAttributes(
attrs,
R.styleable.OnboardingRadioButton,
0, 0
) {
key = getResourceId(R.styleable.OnboardingRadioButton_onboardingKey, 0)
}
}
@ -37,7 +31,7 @@ class OnboardingRadioButton(context: Context, attrs: AttributeSet) : AppCompatRa
radioGroups.add(radioButton)
}
fun onClickListener(listener: (() -> Unit)) {
fun onClickListener(listener: () -> Unit) {
clickListener = listener
}
@ -51,12 +45,13 @@ class OnboardingRadioButton(context: Context, attrs: AttributeSet) : AppCompatRa
private fun updateRadioValue(isChecked: Boolean) {
this.isChecked = isChecked
Settings.getInstance(context).preferences.edit().putBoolean(context.getString(key), isChecked)
.apply()
Settings.getInstance(context).preferences.edit {
putBoolean(context.getString(key), isChecked)
}
}
private fun toggleRadioGroups() {
if (this.isChecked) {
if (isChecked) {
radioGroups.forEach { it.updateRadioValue(false) }
}
}

@ -2,22 +2,24 @@
<!-- 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/. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardDark"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="@style/OnboardingCardDark"
android:id="@+id/onboarding_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:text="@string/onboarding_firefox_account_header"
android:textAppearance="@style/Header16TextStyle"
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
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/onboarding_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp">
<TextView
android:id="@+id/header_text"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/onboarding_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/onboarding_header"
android:textAppearance="@style/HeaderTextStyle"
android:textSize="22sp" />
</FrameLayout>
android:layout_marginBottom="8dp">
<TextView
android:id="@+id/header_text"
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
- 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/. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardLight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/header_text"
app:drawableStartCompat="@drawable/ic_onboarding_privacy_notice"
android:drawablePadding="12dp"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardLight"
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" />
android:layout_height="wrap_content">
<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" />
android:id="@+id/header_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/onboarding_privacy_notice_header"
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
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">
<TextView
android:layout_width="wrap_content"
android:id="@+id/read_button"
android:layout_width="match_parent"
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" />
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>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -2,43 +2,36 @@
<!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardLight"
android:layout_width="match_parent"
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" />
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardLight"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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" />
android:id="@+id/header_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:drawableStart="@drawable/ic_onboarding_private_browsing"
android:drawablePadding="12dp"
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:text="@string/onboarding_private_browsing_description"
android:textAppearance="@style/Body14TextStyle"
android:layout_marginTop="14dp"
app:layout_constraintTop_toBottomOf="@id/private_browsing_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
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>

@ -2,15 +2,12 @@
<!-- 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/. -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/onboarding_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp">
<TextView
android:id="@+id/section_header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/HeaderTextStyle" tools:text="@tools:sample/lorem"/>
</FrameLayout>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/section_header_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/HeaderTextStyle"
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
- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardLight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/onboarding_card"
style="@style/OnboardingCardLight"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<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"/>
android:id="@+id/header_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/onboarding_tracking_protection_header"
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="parent" />
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:text="@string/onboarding_tracking_protection_description"
android:textAppearance="@style/Body14TextStyle"
android:layout_marginTop="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/header_text"
app:layout_constraintBottom_toBottomOf="parent"/>
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>

@ -3,27 +3,27 @@
- 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/. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
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"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/private_session_description_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="none"
android:gravity="center_vertical"
android:scrollHorizontally="false"
android:text="@string/private_browsing_explanation"
android:textColor="?primaryText"
android:textSize="14sp" />
</LinearLayout>
android:layout_margin="16dp"
android:orientation="vertical">
<TextView
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_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…
Cancel
Save