1
0
Fork 0

Cache findViewById calls in session control (#10575)

master
Tiger Oakes 2020-05-12 14:05:08 -07:00 committed by GitHub
parent 9a30d57db9
commit f7b4f1c959
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 114 additions and 111 deletions

View File

@ -0,0 +1,13 @@
package org.mozilla.fenix.ext
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
/**
* A base class for all recycler view holders supporting Android Extensions-style view access.
* This allows views to be used without an `itemView.<id>` prefix, and additionally caches them.
*/
abstract class ViewHolder(
override val containerView: View
) : RecyclerView.ViewHolder(containerView), LayoutContainer

View File

@ -904,7 +904,7 @@ class HomeFragment : Fragment() {
val viewHolder =
sessionControlView!!.view.findViewHolderForAdapterPosition(indexOfCollection)
val border =
(viewHolder as? CollectionViewHolder)?.view?.findViewById<View>(R.id.selected_border)
(viewHolder as? CollectionViewHolder)?.itemView?.findViewById<View>(R.id.selected_border)
val listener = object : Animator.AnimatorListener {
override fun onAnimationCancel(animation: Animator?) {
border?.visibility = View.GONE

View File

@ -8,14 +8,12 @@ import android.content.Context
import android.view.View
import androidx.core.graphics.BlendModeColorFilterCompat.createBlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat.SRC_IN
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.collection_home_list_row.*
import kotlinx.android.synthetic.main.collection_home_list_row.view.*
import mozilla.components.browser.menu.BrowserMenuBuilder
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
import mozilla.components.feature.tab.collections.TabCollection
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.ViewHolder
import org.mozilla.fenix.ext.getIconColor
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.removeAndDisable
@ -25,11 +23,9 @@ import org.mozilla.fenix.home.sessioncontrol.CollectionInteractor
import org.mozilla.fenix.theme.ThemeManager
class CollectionViewHolder(
val view: View,
val interactor: CollectionInteractor,
override val containerView: View? = view
) :
RecyclerView.ViewHolder(view), LayoutContainer {
view: View,
val interactor: CollectionInteractor
) : ViewHolder(view) {
private lateinit var collection: TabCollection
private var expanded = false
@ -71,32 +67,32 @@ class CollectionViewHolder(
}
private fun updateCollectionUI() {
view.collection_title.text = collection.title
collection_title.text = collection.title
view.isActivated = expanded
itemView.isActivated = expanded
if (expanded) {
view.collection_share_button.apply {
collection_share_button.apply {
showAndEnable()
increaseTapArea(buttonIncreaseDps)
}
view.collection_overflow_button.apply {
collection_overflow_button.apply {
showAndEnable()
increaseTapArea(buttonIncreaseDps)
}
} else {
view.collection_share_button.apply {
collection_share_button.apply {
removeAndDisable()
removeTouchDelegate()
}
view.collection_overflow_button.apply {
collection_overflow_button.apply {
removeAndDisable()
removeTouchDelegate()
}
}
view.collection_icon.colorFilter = createBlendModeColorFilterCompat(
collection.getIconColor(view.context),
collection_icon.colorFilter = createBlendModeColorFilterCompat(
collection.getIconColor(itemView.context),
SRC_IN
)
}

View File

@ -6,19 +6,19 @@ package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.view.View
import androidx.annotation.StringRes
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.no_content_message.view.*
import kotlinx.android.synthetic.main.no_content_message.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.ViewHolder
open class NoContentMessageViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
open class NoContentMessageViewHolder(view: View) : ViewHolder(view) {
fun bind(
@StringRes header: Int,
@StringRes description: Int
) {
with(view.context) {
view.no_content_header.text = getString(header)
view.no_content_description.text = getString(description)
with(itemView.context) {
no_content_header.text = getString(header)
no_content_description.text = getString(description)
}
}

View File

@ -8,12 +8,10 @@ import android.view.View
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.no_content_message_with_action.view.*
import kotlinx.android.synthetic.main.no_content_message_with_action.*
import org.mozilla.fenix.R
class NoContentMessageWithActionViewHolder(
private val view: View
) : NoContentMessageViewHolder(view) {
class NoContentMessageWithActionViewHolder(view: View) : NoContentMessageViewHolder(view) {
/**
* @param header ID of string resource for title text.
@ -31,12 +29,12 @@ class NoContentMessageWithActionViewHolder(
listener: (() -> Unit)? = null
) {
super.bind(header, description)
with(view.context) {
with(itemView.context) {
if (buttonIcon != 0 || buttonText != 0) {
view.add_new_tab_button.apply {
add_new_tab_button.apply {
isVisible = true
setIcon(getDrawable(buttonIcon))
icon = getDrawable(buttonIcon)
text = getString(buttonText)
setOnClickListener {
listener?.invoke()

View File

@ -9,20 +9,20 @@ import android.view.View
import android.widget.PopupWindow
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.tab_header.view.*
import kotlinx.android.synthetic.main.tab_header.*
import mozilla.components.browser.menu.BrowserMenu
import mozilla.components.browser.menu.BrowserMenuBuilder
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.ViewHolder
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
class TabHeaderViewHolder(
private val view: View,
view: View,
private val interactor: SessionControlInteractor
) : RecyclerView.ViewHolder(view) {
) : ViewHolder(view) {
private var isPrivate = false
private var tabsMenu: TabHeaderMenu
@ -39,34 +39,28 @@ class TabHeaderViewHolder(
}
}
view.apply {
share_tabs_button.run {
setOnClickListener {
interactor.onShareTabs()
}
}
share_tabs_button.setOnClickListener {
interactor.onShareTabs()
}
close_tabs_button.run {
setOnClickListener {
view.context.components.analytics.metrics.track(Event.PrivateBrowsingGarbageIconTapped)
interactor.onCloseAllTabs(true)
}
}
close_tabs_button.setOnClickListener {
it.context.components.analytics.metrics.track(Event.PrivateBrowsingGarbageIconTapped)
interactor.onCloseAllTabs(true)
}
tabs_overflow_button.run {
var menu: PopupWindow? = null
setOnClickListener {
if (menu == null) {
menu = tabsMenu.menuBuilder
.build(view.context)
.show(
anchor = it,
orientation = BrowserMenu.Orientation.DOWN,
onDismiss = { menu = null }
)
} else {
menu?.dismiss()
}
tabs_overflow_button.run {
var menu: PopupWindow? = null
setOnClickListener {
if (menu == null) {
menu = tabsMenu.menuBuilder
.build(it.context)
.show(
anchor = it,
orientation = BrowserMenu.Orientation.DOWN,
onDismiss = { menu = null }
)
} else {
menu?.dismiss()
}
}
}
@ -78,10 +72,10 @@ class TabHeaderViewHolder(
val headerTextResourceId =
if (isPrivate) R.string.tabs_header_private_tabs_title else R.string.tab_header_label
view.header_text.text = view.context.getString(headerTextResourceId)
view.share_tabs_button.isInvisible = !isPrivate || !hasTabs
view.close_tabs_button.isInvisible = !isPrivate || !hasTabs
view.tabs_overflow_button.isVisible = !isPrivate && hasTabs
header_text.text = itemView.context.getString(headerTextResourceId)
share_tabs_button.isInvisible = !isPrivate || !hasTabs
close_tabs_button.isInvisible = !isPrivate || !hasTabs
tabs_overflow_button.isVisible = !isPrivate && hasTabs
}
class TabHeaderMenu(

View File

@ -8,16 +8,12 @@ import android.graphics.Outline
import android.view.View
import android.view.ViewOutlineProvider
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.list_element.list_element_title
import kotlinx.android.synthetic.main.list_element.list_item_action_button
import kotlinx.android.synthetic.main.list_element.list_item_favicon
import kotlinx.android.synthetic.main.list_element.list_item_url
import kotlinx.android.synthetic.main.list_element.*
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.util.dpToFloat
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.ViewHolder
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.loadIntoView
@ -26,11 +22,10 @@ import org.mozilla.fenix.home.sessioncontrol.CollectionInteractor
import mozilla.components.feature.tab.collections.Tab as ComponentTab
class TabInCollectionViewHolder(
val view: View,
view: View,
val interactor: CollectionInteractor,
private val differentLastItem: Boolean = false,
override val containerView: View? = view
) : RecyclerView.ViewHolder(view), LayoutContainer {
private val differentLastItem: Boolean = false
) : ViewHolder(view) {
lateinit var collection: TabCollection
private set
@ -52,7 +47,7 @@ class TabInCollectionViewHolder(
}
}
view.setOnClickListener {
itemView.setOnClickListener {
interactor.onCollectionOpenTabClicked(tab)
}
@ -70,16 +65,17 @@ class TabInCollectionViewHolder(
}
private fun updateTabUI() {
list_item_url.text = tab.url.toShortUrl(view.context.components.publicSuffixList)
val context = itemView.context
list_item_url.text = tab.url.toShortUrl(context.components.publicSuffixList)
list_element_title.text = tab.title
list_item_favicon.context.components.core.icons.loadIntoView(list_item_favicon, tab.url)
// If last item and we want to change UI for it
if (isLastItem && differentLastItem) {
view.background = AppCompatResources.getDrawable(view.context, R.drawable.rounded_bottom_corners)
itemView.background = AppCompatResources.getDrawable(context, R.drawable.rounded_bottom_corners)
} else {
view.setBackgroundColor(view.context.getColorFromAttr(R.attr.above))
itemView.setBackgroundColor(context.getColorFromAttr(R.attr.above))
}
}

View File

@ -9,13 +9,12 @@ import android.graphics.Outline
import android.view.View
import android.view.ViewOutlineProvider
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.tab_list_row.*
import mozilla.components.browser.state.state.MediaState
import mozilla.components.support.ktx.android.util.dpToFloat
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.ViewHolder
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.loadIntoView
@ -27,10 +26,8 @@ import org.mozilla.fenix.home.sessioncontrol.TabSessionInteractor
class TabViewHolder(
view: View,
interactor: TabSessionInteractor,
override val containerView: View? = view
) :
RecyclerView.ViewHolder(view), LayoutContainer {
interactor: TabSessionInteractor
) : ViewHolder(view) {
internal var tab: Tab? = null

View File

@ -7,7 +7,6 @@ package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.google.android.flexbox.FlexboxLayoutManager
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.component_top_sites.view.*
import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.R
@ -16,9 +15,9 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.topsites.TopSitesAdapte
class TopSiteViewHolder(
view: View,
interactor: TopSiteInteractor,
override val containerView: View? = view
) : RecyclerView.ViewHolder(view), LayoutContainer {
interactor: TopSiteInteractor
) : RecyclerView.ViewHolder(view) {
private val topSitesAdapter = TopSitesAdapter(interactor)
init {

View File

@ -5,7 +5,7 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.content.res.AppCompatResources.getDrawable
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.onboarding_automatic_signin.view.*
@ -19,8 +19,10 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.ext.components
class OnboardingAutomaticSignInViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
class OnboardingAutomaticSignInViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private lateinit var shareableAccount: ShareableAccount
private val headerText = view.header_text
init {
view.turn_on_sync_button.setOnClickListener {
@ -57,11 +59,11 @@ class OnboardingAutomaticSignInViewHolder(private val view: View) : RecyclerView
fun bind(account: ShareableAccount) {
shareableAccount = account
view.header_text.text = view.context.getString(
headerText.text = itemView.context.getString(
R.string.onboarding_firefox_account_auto_signin_header_2, account.email
)
val icon = AppCompatResources.getDrawable(view.context, R.drawable.ic_onboarding_avatar_anonymous)
view.header_text.putCompoundDrawablesRelativeWithIntrinsicBounds(start = icon)
val icon = getDrawable(itemView.context, R.drawable.ic_onboarding_avatar_anonymous)
headerText.putCompoundDrawablesRelativeWithIntrinsicBounds(start = icon)
}
companion object {

View File

@ -14,7 +14,10 @@ import mozilla.components.support.ktx.android.view.putCompoundDrawablesRelativeW
import org.mozilla.fenix.R
import org.mozilla.fenix.home.HomeFragmentDirections
class OnboardingManualSignInViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
class OnboardingManualSignInViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val headerText = view.header_text
init {
view.turn_on_sync_button.setOnClickListener {
val directions = HomeFragmentDirections.actionGlobalTurnOnSync()
@ -23,11 +26,13 @@ class OnboardingManualSignInViewHolder(private val view: View) : RecyclerView.Vi
}
fun bind() {
val appName = view.context.getString(R.string.app_name)
view.header_text.text = view.context.getString(R.string.onboarding_firefox_account_header, appName)
val icon = AppCompatResources.getDrawable(view.context, R.drawable.ic_onboarding_firefox_accounts)
icon?.setTint(ContextCompat.getColor(view.context, R.color.white_color))
view.header_text.putCompoundDrawablesRelativeWithIntrinsicBounds(start = icon)
val context = itemView.context
val appName = context.getString(R.string.app_name)
headerText.text = context.getString(R.string.onboarding_firefox_account_header, appName)
val icon = AppCompatResources.getDrawable(context, R.drawable.ic_onboarding_firefox_accounts)
icon?.setTint(ContextCompat.getColor(context, R.color.white_color))
headerText.putCompoundDrawablesRelativeWithIntrinsicBounds(start = icon)
}
companion object {

View File

@ -10,10 +10,12 @@ import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.onboarding_section_header.view.*
import org.mozilla.fenix.R
class OnboardingSectionHeaderViewHolder(private val view: View) : RecyclerView.ViewHolder(view) {
class OnboardingSectionHeaderViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val sectionHeader = view.section_header_text
fun bind(labelBuilder: (Context) -> String) {
view.section_header_text.text = labelBuilder(view.context)
sectionHeader.text = labelBuilder(itemView.context)
}
companion object {

View File

@ -6,21 +6,22 @@ package org.mozilla.fenix.home.sessioncontrol.viewholders.topsites
import android.content.Context
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.top_site_item.*
import kotlinx.android.synthetic.main.top_site_item.view.*
import mozilla.components.browser.menu.BrowserMenuBuilder
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.ViewHolder
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.loadIntoView
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
import org.mozilla.fenix.settings.SupportUtils
class TopSiteItemViewHolder(
private val view: View,
view: View,
private val interactor: TopSiteInteractor
) : RecyclerView.ViewHolder(view) {
) : ViewHolder(view) {
private lateinit var topSite: TopSite
private var topSiteMenu: TopSiteItemMenu
@ -34,11 +35,11 @@ class TopSiteItemViewHolder(
}
}
view.top_site_item.setOnClickListener {
top_site_item.setOnClickListener {
interactor.onSelectTopSite(topSite.url)
}
view.top_site_item.setOnLongClickListener() {
top_site_item.setOnLongClickListener() {
topSiteMenu.menuBuilder.build(view.context).show(anchor = it.top_site_title)
return@setOnLongClickListener true
}
@ -46,13 +47,13 @@ class TopSiteItemViewHolder(
fun bind(topSite: TopSite) {
this.topSite = topSite
view.top_site_title.text = topSite.title
when {
topSite.url == SupportUtils.POCKET_TRENDING_URL -> {
view.favicon_image.setImageDrawable(view.context.getDrawable(R.drawable.ic_pocket))
top_site_title.text = topSite.title
when (topSite.url) {
SupportUtils.POCKET_TRENDING_URL -> {
favicon_image.setImageDrawable(itemView.context.getDrawable(R.drawable.ic_pocket))
}
else -> {
view.context.components.core.icons.loadIntoView(view.favicon_image, topSite.url)
itemView.context.components.core.icons.loadIntoView(favicon_image, topSite.url)
}
}
}