1
0
Fork 0

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
Tiger Oakes 2019-06-26 19:03:06 -04:00 committed by Sawyer Blatz
parent 4994554576
commit e8bd090a8e
19 changed files with 317 additions and 285 deletions

View File

@ -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
*/

View File

@ -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)
}

View File

@ -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()
}
}

View File

@ -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 {

View File

@ -23,6 +23,7 @@ class OnboardingFinishViewHolder(
actionEmitter.onNext(OnboardingAction.Finish)
}
}
companion object {
const val LAYOUT_ID = R.layout.onboarding_finish
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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

View File

@ -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
}
}

View File

@ -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 {

View File

@ -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"
}
}

View File

@ -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) }
}
}

View File

@ -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" />

View File

@ -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>

View File

@ -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">
<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"
app:drawableStartCompat="@drawable/ic_onboarding_privacy_notice"
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:id="@+id/header_text"
android:layout_width="0dp"
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: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"
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>

View File

@ -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" />
<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"
<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: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:layout_height="wrap_content">
<TextView
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: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>

View File

@ -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" />

View File

@ -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">
<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"
<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: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:layout_height="wrap_content">
<TextView
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="@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>

View File

@ -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>