improve custom tabs toolbar

This commit is contained in:
Fabian Freund
2026-02-11 09:41:01 +01:00
parent 8e25814a67
commit 8c42edb37b
5 changed files with 165 additions and 67 deletions
@@ -148,13 +148,13 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
true true
).apply { ).apply {
elevation = 8f elevation = 10f
isOutsideTouchable = true isOutsideTouchable = true
} }
activePopup = popup activePopup = popup
val iconColor = MaterialColors.getColor(anchorView, com.google.android.material.R.attr.colorOnSurface) val iconColor = MaterialColors.getColor(anchorView, com.google.android.material.R.attr.colorOnSurfaceVariant)
val disabledColor = MaterialColors.getColor(anchorView, com.google.android.material.R.attr.colorOnSurfaceVariant) val disabledColor = MaterialColors.getColor(anchorView, com.google.android.material.R.attr.colorOutline)
// Navigation row icons // Navigation row icons
val canGoBack = customTab.content.canGoBack val canGoBack = customTab.content.canGoBack
@@ -163,7 +163,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
val backBtn = menuView.findViewById<ImageButton>(R.id.menuBack) val backBtn = menuView.findViewById<ImageButton>(R.id.menuBack)
val forwardBtn = menuView.findViewById<ImageButton>(R.id.menuForward) val forwardBtn = menuView.findViewById<ImageButton>(R.id.menuForward)
backBtn.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_arrow_left, 20, if (canGoBack) iconColor else disabledColor)) backBtn.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_arrow_left, 22, if (canGoBack) iconColor else disabledColor))
backBtn.isEnabled = canGoBack backBtn.isEnabled = canGoBack
backBtn.alpha = if (canGoBack) 1.0f else 0.38f backBtn.alpha = if (canGoBack) 1.0f else 0.38f
backBtn.setOnClickListener { backBtn.setOnClickListener {
@@ -171,7 +171,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
popup.dismiss() popup.dismiss()
} }
forwardBtn.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_arrow_right, 20, if (canGoForward) iconColor else disabledColor)) forwardBtn.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_arrow_right, 22, if (canGoForward) iconColor else disabledColor))
forwardBtn.isEnabled = canGoForward forwardBtn.isEnabled = canGoForward
forwardBtn.alpha = if (canGoForward) 1.0f else 0.38f forwardBtn.alpha = if (canGoForward) 1.0f else 0.38f
forwardBtn.setOnClickListener { forwardBtn.setOnClickListener {
@@ -181,13 +181,13 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
// Menu item icons // Menu item icons
menuView.findViewById<ImageView>(R.id.menuRefreshIcon) menuView.findViewById<ImageView>(R.id.menuRefreshIcon)
.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_refresh, 20, iconColor)) .setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_refresh, 24, iconColor))
menuView.findViewById<ImageView>(R.id.menuShareIcon) menuView.findViewById<ImageView>(R.id.menuShareIcon)
.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_share_variant, 20, iconColor)) .setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_share_variant, 24, iconColor))
menuView.findViewById<ImageView>(R.id.menuDesktopIcon) menuView.findViewById<ImageView>(R.id.menuDesktopIcon)
.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_monitor, 20, iconColor)) .setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_monitor, 24, iconColor))
menuView.findViewById<ImageView>(R.id.menuOpenInBrowserIcon) menuView.findViewById<ImageView>(R.id.menuOpenInBrowserIcon)
.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_open_in_new, 20, iconColor)) .setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_open_in_new, 24, iconColor))
// Refresh // Refresh
menuView.findViewById<View>(R.id.menuRefresh).setOnClickListener { menuView.findViewById<View>(R.id.menuRefresh).setOnClickListener {
@@ -7,12 +7,15 @@
package eu.weblibre.flutter_mozilla_components.widget package eu.weblibre.flutter_mozilla_components.widget
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable
import android.net.Uri
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources
import com.google.android.material.card.MaterialCardView import com.google.android.material.card.MaterialCardView
import com.google.android.material.color.MaterialColors import com.google.android.material.color.MaterialColors
import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsDrawable
@@ -44,6 +47,7 @@ class CustomTabToolbar @JvmOverloads constructor(
private val toolbarCard: MaterialCardView private val toolbarCard: MaterialCardView
private val closeButton: ImageButton private val closeButton: ImageButton
private val securityIcon: ImageView private val securityIcon: ImageView
private val titleText: TextView
private val urlText: TextView private val urlText: TextView
private val shareButton: ImageButton private val shareButton: ImageButton
private val openInBrowserButton: ImageButton private val openInBrowserButton: ImageButton
@@ -52,6 +56,7 @@ class CustomTabToolbar @JvmOverloads constructor(
private var sessionId: String? = null private var sessionId: String? = null
private var store: BrowserStore? = null private var store: BrowserStore? = null
private var urlScope: CoroutineScope? = null private var urlScope: CoroutineScope? = null
private var titleScope: CoroutineScope? = null
private var securityScope: CoroutineScope? = null private var securityScope: CoroutineScope? = null
var onCloseListener: (() -> Unit)? = null var onCloseListener: (() -> Unit)? = null
@@ -65,6 +70,7 @@ class CustomTabToolbar @JvmOverloads constructor(
toolbarCard = findViewById(R.id.toolbarCard) toolbarCard = findViewById(R.id.toolbarCard)
closeButton = findViewById(R.id.closeButton) closeButton = findViewById(R.id.closeButton)
securityIcon = findViewById(R.id.securityIcon) securityIcon = findViewById(R.id.securityIcon)
titleText = findViewById(R.id.titleText)
urlText = findViewById(R.id.urlText) urlText = findViewById(R.id.urlText)
shareButton = findViewById(R.id.shareButton) shareButton = findViewById(R.id.shareButton)
openInBrowserButton = findViewById(R.id.openInBrowserButton) openInBrowserButton = findViewById(R.id.openInBrowserButton)
@@ -86,17 +92,21 @@ class CustomTabToolbar @JvmOverloads constructor(
toolbarColor?.let { applyCustomColors(it) } toolbarColor?.let { applyCustomColors(it) }
store.state.findCustomTab(sessionId)?.let { tab -> store.state.findCustomTab(sessionId)?.let { tab ->
updateTitle(tab)
updateUrl(tab) updateUrl(tab)
updateSecurityIcon(tab) updateSecurityIcon(tab)
} }
observeUrlChanges() observeUrlChanges()
observeTitleChanges()
observeSecurityChanges() observeSecurityChanges()
} }
fun unbind() { fun unbind() {
urlScope?.cancel() urlScope?.cancel()
urlScope = null urlScope = null
titleScope?.cancel()
titleScope = null
securityScope?.cancel() securityScope?.cancel()
securityScope = null securityScope = null
} }
@@ -109,6 +119,7 @@ class CustomTabToolbar @JvmOverloads constructor(
val surfaceColor = MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurface) val surfaceColor = MaterialColors.getColor(this, com.google.android.material.R.attr.colorSurface)
val onSurfaceColor = MaterialColors.getColor(this, com.google.android.material.R.attr.colorOnSurface) val onSurfaceColor = MaterialColors.getColor(this, com.google.android.material.R.attr.colorOnSurface)
toolbarCard.setCardBackgroundColor(surfaceColor) toolbarCard.setCardBackgroundColor(surfaceColor)
titleText.setTextColor(onSurfaceColor)
urlText.setTextColor(onSurfaceColor) urlText.setTextColor(onSurfaceColor)
} }
@@ -117,7 +128,10 @@ class CustomTabToolbar @JvmOverloads constructor(
closeButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_close, 20, iconColor)) closeButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_close, 20, iconColor))
shareButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_share_variant, 18, iconColor)) shareButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_share_variant, 18, iconColor))
openInBrowserButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_open_in_new, 18, iconColor)) openInBrowserButton.setImageDrawable(
weblibreLogoIcon()
?: mdiIcon(CommunityMaterial.Icon3.cmd_open_in_new, 18, iconColor)
)
menuButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_dots_vertical, 18, iconColor)) menuButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_dots_vertical, 18, iconColor))
} }
@@ -128,14 +142,31 @@ class CustomTabToolbar @JvmOverloads constructor(
} else { } else {
android.graphics.Color.BLACK android.graphics.Color.BLACK
} }
titleText.setTextColor(textColor)
urlText.setTextColor(textColor) urlText.setTextColor(textColor)
closeButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_close, 20, textColor)) closeButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_close, 20, textColor))
shareButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_share_variant, 18, textColor)) shareButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_share_variant, 18, textColor))
openInBrowserButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_open_in_new, 18, textColor)) openInBrowserButton.setImageDrawable(
weblibreLogoIcon()
?: mdiIcon(CommunityMaterial.Icon3.cmd_open_in_new, 18, textColor)
)
menuButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_dots_vertical, 18, textColor)) menuButton.setImageDrawable(mdiIcon(CommunityMaterial.Icon.cmd_dots_vertical, 18, textColor))
} }
private fun weblibreLogoIcon(): Drawable? = runCatching {
val resId = context.resources.getIdentifier(
"ic_launcher_foreground",
"drawable",
context.packageName,
)
if (resId == 0) {
null
} else {
AppCompatResources.getDrawable(context, resId)
}
}.getOrNull()?.mutate()
private fun isDarkColor(color: Int): Boolean { private fun isDarkColor(color: Int): Boolean {
val darkness = 1 - (0.299 * android.graphics.Color.red(color) + val darkness = 1 - (0.299 * android.graphics.Color.red(color) +
0.587 * android.graphics.Color.green(color) + 0.587 * android.graphics.Color.green(color) +
@@ -151,7 +182,22 @@ class CustomTabToolbar @JvmOverloads constructor(
flow flow
.mapNotNull { state -> state.findCustomTab(sessionId) } .mapNotNull { state -> state.findCustomTab(sessionId) }
.ifAnyChanged { tab -> arrayOf(tab.content.url) } .ifAnyChanged { tab -> arrayOf(tab.content.url) }
.collect { tab -> updateUrl(tab) } .collect { tab ->
updateUrl(tab)
updateTitle(tab)
}
}
}
private fun observeTitleChanges() {
val sessionId = this.sessionId ?: return
val store = this.store ?: return
titleScope = store.flowScoped { flow ->
flow
.mapNotNull { state -> state.findCustomTab(sessionId) }
.ifAnyChanged { tab -> arrayOf(tab.content.title) }
.collect { tab -> updateTitle(tab) }
} }
} }
@@ -162,22 +208,51 @@ class CustomTabToolbar @JvmOverloads constructor(
securityScope = store.flowScoped { flow -> securityScope = store.flowScoped { flow ->
flow flow
.mapNotNull { state -> state.findCustomTab(sessionId) } .mapNotNull { state -> state.findCustomTab(sessionId) }
.ifAnyChanged { tab -> arrayOf(tab.content.securityInfo.isSecure) } .ifAnyChanged {
tab -> arrayOf(
tab.content.securityInfo.isSecure,
tab.content.securityInfo.host,
tab.content.loading
)
}
.collect { tab -> updateSecurityIcon(tab) } .collect { tab -> updateSecurityIcon(tab) }
} }
} }
private fun updateTitle(tab: CustomTabSessionState) {
val title = tab.content.title
titleText.text = if (title.isBlank()) {
displayHost(tab.content.url)
} else {
title
}
}
private fun updateUrl(tab: CustomTabSessionState) { private fun updateUrl(tab: CustomTabSessionState) {
urlText.text = URLStringUtils.toDisplayUrl(tab.content.url) urlText.text = displayHost(tab.content.url)
}
private fun displayHost(url: String): String {
val host = Uri.parse(url).host
return if (!host.isNullOrBlank()) {
host
} else {
URLStringUtils.toDisplayUrl(url).toString()
}
} }
private fun updateSecurityIcon(tab: CustomTabSessionState) { private fun updateSecurityIcon(tab: CustomTabSessionState) {
if (tab.content.securityInfo.isSecure) { val securityInfoKnown = tab.content.securityInfo.host.isNotBlank()
if (tab.content.loading || !securityInfoKnown) {
val color = MaterialColors.getColor(this, com.google.android.material.R.attr.colorOnSurfaceVariant)
securityIcon.setImageDrawable(mdiIcon(CommunityMaterial.Icon2.cmd_lock_open_outline, 16, color))
} else if (tab.content.securityInfo.isSecure) {
val color = MaterialColors.getColor(this, com.google.android.material.R.attr.colorOnSurfaceVariant) val color = MaterialColors.getColor(this, com.google.android.material.R.attr.colorOnSurfaceVariant)
securityIcon.setImageDrawable(mdiIcon(CommunityMaterial.Icon2.cmd_lock, 16, color)) securityIcon.setImageDrawable(mdiIcon(CommunityMaterial.Icon2.cmd_lock, 16, color))
} else { } else {
val color = MaterialColors.getColor(this, android.R.attr.colorError) val color = MaterialColors.getColor(this, android.R.attr.colorError)
securityIcon.setImageDrawable(mdiIcon(CommunityMaterial.Icon3.cmd_web, 16, color)) securityIcon.setImageDrawable(mdiIcon(CommunityMaterial.Icon2.cmd_lock_open_outline, 16, color))
} }
} }
@@ -5,6 +5,9 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android" <shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<solid android:color="?attr/colorSurfaceContainer" /> <solid android:color="?attr/colorSurfaceContainerHigh" />
<corners android:radius="16dp" /> <corners android:radius="20dp" />
<stroke
android:width="1dp"
android:color="?attr/colorOutlineVariant" />
</shape> </shape>
@@ -8,29 +8,29 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/custom_tab_menu_bg" android:background="@drawable/custom_tab_menu_bg"
android:paddingVertical="4dp" android:paddingVertical="8dp"
android:minWidth="192dp"> android:minWidth="220dp">
<!-- Navigation row: Back / Forward --> <!-- Navigation row: Back / Forward -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="48dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center" android:gravity="center"
android:paddingHorizontal="12dp"> android:paddingHorizontal="14dp">
<ImageButton <ImageButton
android:id="@+id/menuBack" android:id="@+id/menuBack"
android:layout_width="36dp" android:layout_width="40dp"
android:layout_height="36dp" android:layout_height="40dp"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="center" android:scaleType="center"
android:contentDescription="@string/custom_tab_navigate_back" /> android:contentDescription="@string/custom_tab_navigate_back" />
<ImageButton <ImageButton
android:id="@+id/menuForward" android:id="@+id/menuForward"
android:layout_width="36dp" android:layout_width="40dp"
android:layout_height="36dp" android:layout_height="40dp"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="center" android:scaleType="center"
android:contentDescription="@string/custom_tab_navigate_forward" /> android:contentDescription="@string/custom_tab_navigate_forward" />
@@ -40,33 +40,33 @@
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_marginHorizontal="12dp" android:layout_marginHorizontal="14dp"
android:layout_marginVertical="4dp" android:layout_marginVertical="6dp"
android:background="?attr/colorOutlineVariant" /> android:background="?attr/colorOutlineVariant" />
<!-- Refresh --> <!-- Refresh -->
<LinearLayout <LinearLayout
android:id="@+id/menuRefresh" android:id="@+id/menuRefresh"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="48dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingHorizontal="12dp" android:paddingHorizontal="14dp"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:focusable="true"> android:focusable="true">
<ImageView <ImageView
android:id="@+id/menuRefreshIcon" android:id="@+id/menuRefreshIcon"
android:layout_width="20dp" android:layout_width="24dp"
android:layout_height="20dp" android:layout_height="24dp"
android:layout_marginEnd="12dp" /> android:layout_marginEnd="14dp" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/custom_tab_refresh" android:text="@string/custom_tab_refresh"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface" /> android:textColor="?attr/colorOnSurface" />
</LinearLayout> </LinearLayout>
@@ -74,25 +74,25 @@
<LinearLayout <LinearLayout
android:id="@+id/menuShare" android:id="@+id/menuShare"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="48dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingHorizontal="12dp" android:paddingHorizontal="14dp"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:focusable="true"> android:focusable="true">
<ImageView <ImageView
android:id="@+id/menuShareIcon" android:id="@+id/menuShareIcon"
android:layout_width="20dp" android:layout_width="24dp"
android:layout_height="20dp" android:layout_height="24dp"
android:layout_marginEnd="12dp" /> android:layout_marginEnd="14dp" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/custom_tab_share" android:text="@string/custom_tab_share"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface" /> android:textColor="?attr/colorOnSurface" />
</LinearLayout> </LinearLayout>
@@ -100,26 +100,26 @@
<LinearLayout <LinearLayout
android:id="@+id/menuDesktopSite" android:id="@+id/menuDesktopSite"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="48dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingHorizontal="12dp" android:paddingHorizontal="14dp"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:focusable="true"> android:focusable="true">
<ImageView <ImageView
android:id="@+id/menuDesktopIcon" android:id="@+id/menuDesktopIcon"
android:layout_width="20dp" android:layout_width="24dp"
android:layout_height="20dp" android:layout_height="24dp"
android:layout_marginEnd="12dp" /> android:layout_marginEnd="14dp" />
<TextView <TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text="@string/custom_tab_desktop_site" android:text="@string/custom_tab_desktop_site"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface" /> android:textColor="?attr/colorOnSurface" />
<com.google.android.material.materialswitch.MaterialSwitch <com.google.android.material.materialswitch.MaterialSwitch
@@ -132,25 +132,25 @@
<LinearLayout <LinearLayout
android:id="@+id/menuOpenInBrowser" android:id="@+id/menuOpenInBrowser"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="48dp"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingHorizontal="12dp" android:paddingHorizontal="14dp"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:focusable="true"> android:focusable="true">
<ImageView <ImageView
android:id="@+id/menuOpenInBrowserIcon" android:id="@+id/menuOpenInBrowserIcon"
android:layout_width="20dp" android:layout_width="24dp"
android:layout_height="20dp" android:layout_height="24dp"
android:layout_marginEnd="12dp" /> android:layout_marginEnd="14dp" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/custom_tab_open_in_browser" android:text="@string/custom_tab_open_in_browser"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyLarge"
android:textColor="?attr/colorOnSurface" /> android:textColor="?attr/colorOnSurface" />
</LinearLayout> </LinearLayout>
@@ -13,8 +13,8 @@
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/toolbarCard" android:id="@+id/toolbarCard"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="64dp"
app:cardCornerRadius="28dp" app:cardCornerRadius="32dp"
app:cardElevation="3dp" app:cardElevation="3dp"
app:strokeWidth="0dp" app:strokeWidth="0dp"
app:cardBackgroundColor="?attr/colorSurface"> app:cardBackgroundColor="?attr/colorSurface">
@@ -35,31 +35,50 @@
android:scaleType="center" android:scaleType="center"
android:contentDescription="@string/mozac_feature_customtabs_exit_button" /> android:contentDescription="@string/mozac_feature_customtabs_exit_button" />
<!-- URL Section with Security Indicator --> <!-- Leading security icon + title/hostname section -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" android:layout_weight="1"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingHorizontal="8dp"> android:paddingHorizontal="8dp"
android:paddingVertical="6dp">
<ImageView <ImageView
android:id="@+id/securityIcon" android:id="@+id/securityIcon"
android:layout_width="18dp" android:layout_width="18dp"
android:layout_height="18dp" android:layout_height="18dp"
android:layout_marginEnd="6dp" android:layout_marginEnd="8dp"
android:contentDescription="@string/mozac_feature_customtabs_security_indicator" /> android:contentDescription="@string/mozac_feature_customtabs_security_indicator" />
<TextView <LinearLayout
android:id="@+id/urlText" android:layout_width="0dp"
android:layout_width="wrap_content" android:layout_height="match_parent"
android:layout_height="wrap_content" android:layout_weight="1"
android:ellipsize="end" android:orientation="vertical"
android:maxLines="1" android:gravity="center_vertical">
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?attr/colorOnSurface" <TextView
android:textSize="14sp" /> android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textColor="?attr/colorOnSurface"
android:textSize="14sp" />
<TextView
android:id="@+id/urlText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceBodySmall"
android:textColor="?attr/colorOnSurface"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout> </LinearLayout>
<!-- Action Buttons --> <!-- Action Buttons -->
@@ -76,7 +95,8 @@
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:background="?attr/selectableItemBackgroundBorderless" android:background="?attr/selectableItemBackgroundBorderless"
android:scaleType="center" android:padding="8dp"
android:scaleType="centerInside"
android:contentDescription="@string/custom_tab_open_in_browser" /> android:contentDescription="@string/custom_tab_open_in_browser" />
<ImageButton <ImageButton