Browse Source

Migrate to ViewBinding from Kotlin synthetics in controllers

arkon 5 năm trước cách đây
mục cha
commit
627a720d4b
22 tập tin đã thay đổi với 272 bổ sung300 xóa
  1. 4 0
      app/build.gradle
  2. 0 3
      app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt
  3. 0 6
      app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt
  4. 1 2
      app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/BaseFlexibleViewHolder.kt
  5. 9 13
      app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt
  6. 35 39
      app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt
  7. 8 5
      app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt
  8. 11 10
      app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt
  9. 11 9
      app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt
  10. 12 9
      app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt
  11. 16 22
      app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt
  12. 22 21
      app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt
  13. 9 6
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt
  14. 34 36
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt
  15. 41 54
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt
  16. 15 15
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt
  17. 9 6
      app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt
  18. 0 3
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
  19. 0 3
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt
  20. 10 8
      app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt
  21. 25 24
      app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt
  22. 0 6
      app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt

+ 4 - 0
app/build.gradle

@@ -57,6 +57,10 @@ android {
         }
     }
 
+    viewBinding {
+        enabled = true
+    }
+
     buildTypes {
         debug {
             versionNameSuffix "-${getCommitCount()}"

+ 0 - 3
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt

@@ -20,9 +20,6 @@ import uy.kohesive.injekt.injectLazy
  */
 class DownloadProvider(private val context: Context) {
 
-    /**
-     * Preferences helper.
-     */
     private val preferences: PreferencesHelper by injectLazy()
 
     /**

+ 0 - 6
app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadService.kt

@@ -63,14 +63,8 @@ class DownloadService : Service() {
         }
     }
 
-    /**
-     * Download manager.
-     */
     private val downloadManager: DownloadManager by injectLazy()
 
-    /**
-     * Preferences helper.
-     */
     private val preferences: PreferencesHelper by injectLazy()
 
     /**

+ 1 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/BaseFlexibleViewHolder.kt

@@ -9,8 +9,7 @@ abstract class BaseFlexibleViewHolder(
     view: View,
     adapter: FlexibleAdapter<*>,
     stickyHeader: Boolean = false
-) :
-        FlexibleViewHolder(view, adapter, stickyHeader), LayoutContainer {
+) : FlexibleViewHolder(view, adapter, stickyHeader), LayoutContainer {
 
     override val containerView: View?
         get() = itemView

+ 9 - 13
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/CatalogueController.kt

@@ -20,6 +20,7 @@ import eu.davidea.flexibleadapter.items.IFlexible
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.data.preference.getOrDefault
+import eu.kanade.tachiyomi.databinding.CatalogueMainControllerBinding
 import eu.kanade.tachiyomi.source.CatalogueSource
 import eu.kanade.tachiyomi.source.Source
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
@@ -30,8 +31,6 @@ import eu.kanade.tachiyomi.ui.catalogue.browse.BrowseCatalogueController
 import eu.kanade.tachiyomi.ui.catalogue.global_search.CatalogueSearchController
 import eu.kanade.tachiyomi.ui.catalogue.latest.LatestUpdatesController
 import eu.kanade.tachiyomi.ui.setting.SettingsSourcesController
-import kotlinx.android.synthetic.main.catalogue_main_controller.fast_scroller
-import kotlinx.android.synthetic.main.catalogue_main_controller.recycler
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 
@@ -48,9 +47,6 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
         CatalogueAdapter.OnBrowseClickListener,
         CatalogueAdapter.OnLatestClickListener {
 
-    /**
-     * Application preferences.
-     */
     private val preferences: PreferencesHelper = Injekt.get()
 
     /**
@@ -58,9 +54,8 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
      */
     private var adapter: CatalogueAdapter? = null
 
-    /**
-     * Called when controller is initialized.
-     */
+    private lateinit var binding: CatalogueMainControllerBinding
+
     init {
         // Enable the option menu
         setHasOptionsMenu(true)
@@ -92,7 +87,8 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
      * @return inflated view.
      */
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.catalogue_main_controller, container, false)
+        binding = CatalogueMainControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     /**
@@ -106,10 +102,10 @@ class CatalogueController : NucleusController<CataloguePresenter>(),
         adapter = CatalogueAdapter(this)
 
         // Create recycler and set adapter.
-        recycler.layoutManager = LinearLayoutManager(view.context)
-        recycler.adapter = adapter
-        recycler.addItemDecoration(SourceDividerItemDecoration(view.context))
-        adapter?.fastScroller = fast_scroller
+        binding.recycler.layoutManager = LinearLayoutManager(view.context)
+        binding.recycler.adapter = adapter
+        binding.recycler.addItemDecoration(SourceDividerItemDecoration(view.context))
+        adapter?.fastScroller = binding.fastScroller
 
         requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301)
     }

+ 35 - 39
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt

@@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Category
 import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
+import eu.kanade.tachiyomi.databinding.CatalogueControllerBinding
 import eu.kanade.tachiyomi.source.CatalogueSource
 import eu.kanade.tachiyomi.source.model.FilterList
 import eu.kanade.tachiyomi.source.online.HttpSource
@@ -43,9 +44,6 @@ import eu.kanade.tachiyomi.util.view.visible
 import eu.kanade.tachiyomi.widget.AutofitRecyclerView
 import eu.kanade.tachiyomi.widget.EmptyView
 import java.util.concurrent.TimeUnit
-import kotlinx.android.synthetic.main.catalogue_controller.catalogue_view
-import kotlinx.android.synthetic.main.catalogue_controller.empty_view
-import kotlinx.android.synthetic.main.catalogue_controller.progress
 import kotlinx.android.synthetic.main.main_activity.drawer
 import rx.Observable
 import rx.Subscription
@@ -68,9 +66,6 @@ open class BrowseCatalogueController(bundle: Bundle) :
         putLong(SOURCE_ID_KEY, source.id)
     })
 
-    /**
-     * Preferences helper.
-     */
     private val preferences: PreferencesHelper by injectLazy()
 
     /**
@@ -108,6 +103,8 @@ open class BrowseCatalogueController(bundle: Bundle) :
      */
     private var progressItem: ProgressItem? = null
 
+    private lateinit var binding: CatalogueControllerBinding
+
     init {
         setHasOptionsMenu(true)
     }
@@ -121,7 +118,8 @@ open class BrowseCatalogueController(bundle: Bundle) :
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.catalogue_controller, container, false)
+        binding = CatalogueControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
@@ -133,7 +131,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
 
         navView?.setFilters(presenter.filterItems)
 
-        progress?.visible()
+        binding.progress.visible()
     }
 
     override fun onDestroyView(view: View) {
@@ -180,12 +178,12 @@ open class BrowseCatalogueController(bundle: Bundle) :
         numColumnsSubscription?.unsubscribe()
 
         var oldPosition = RecyclerView.NO_POSITION
-        val oldRecycler = catalogue_view?.getChildAt(1)
+        val oldRecycler = binding.catalogueView.getChildAt(1)
         if (oldRecycler is RecyclerView) {
             oldPosition = (oldRecycler.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
             oldRecycler.adapter = null
 
-            catalogue_view?.removeView(oldRecycler)
+            binding.catalogueView.removeView(oldRecycler)
         }
 
         val recycler = if (presenter.isListMode) {
@@ -196,7 +194,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
                 addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL))
             }
         } else {
-            (catalogue_view.inflate(R.layout.catalogue_recycler_autofit) as AutofitRecyclerView).apply {
+            (binding.catalogueView.inflate(R.layout.catalogue_recycler_autofit) as AutofitRecyclerView).apply {
                 numColumnsSubscription = getColumnsPreferenceForCurrentOrientation().asObservable()
                         .doOnNext { spanCount = it }
                         .skip(1)
@@ -216,7 +214,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
         recycler.setHasFixedSize(true)
         recycler.adapter = adapter
 
-        catalogue_view.addView(recycler, 1)
+        binding.catalogueView.addView(recycler, 1)
 
         if (oldPosition != RecyclerView.NO_POSITION) {
             recycler.layoutManager?.scrollToPosition(oldPosition)
@@ -353,45 +351,43 @@ open class BrowseCatalogueController(bundle: Bundle) :
 
         snack?.dismiss()
 
-        if (catalogue_view != null) {
-            val message = getErrorMessage(error)
-            val retryAction = View.OnClickListener {
+        val message = getErrorMessage(error)
+        val retryAction = View.OnClickListener {
 
-                // If not the first page, show bottom progress bar.
-                if (adapter.mainItemCount > 0 && progressItem != null) {
-                    adapter.addScrollableFooterWithDelay(progressItem!!, 0, true)
-                } else {
-                    showProgressBar()
-                }
-                presenter.requestNext()
+            // If not the first page, show bottom progress bar.
+            if (adapter.mainItemCount > 0 && progressItem != null) {
+                adapter.addScrollableFooterWithDelay(progressItem!!, 0, true)
+            } else {
+                showProgressBar()
             }
+            presenter.requestNext()
+        }
 
-            if (adapter.isEmpty) {
-                val actions = mutableListOf(EmptyView.Action(R.string.action_retry, retryAction))
-                if (presenter.source is HttpSource) {
-                    val openInWebViewAction = View.OnClickListener {
-                        openInWebView()
-                    }
-                    actions += EmptyView.Action(R.string.action_open_in_web_view, openInWebViewAction)
+        if (adapter.isEmpty) {
+            val actions = mutableListOf(EmptyView.Action(R.string.action_retry, retryAction))
+            if (presenter.source is HttpSource) {
+                val openInWebViewAction = View.OnClickListener {
+                    openInWebView()
                 }
+                actions += EmptyView.Action(R.string.action_open_in_web_view, openInWebViewAction)
+            }
 
-                empty_view.show(message, actions)
-            } else {
-                snack = catalogue_view.snack(message, Snackbar.LENGTH_INDEFINITE) {
-                    setAction(R.string.action_retry, retryAction)
-                }
+            binding.emptyView.show(message, actions)
+        } else {
+            snack = binding.catalogueView.snack(message, Snackbar.LENGTH_INDEFINITE) {
+                setAction(R.string.action_retry, retryAction)
             }
         }
     }
 
     private fun getErrorMessage(error: Throwable): String {
         if (error is NoResultsException) {
-            return catalogue_view.context.getString(R.string.no_results_found)
+            return binding.catalogueView.context.getString(R.string.no_results_found)
         }
 
         return when {
             error.message == null -> ""
-            error.message!!.startsWith("HTTP error") -> "${error.message}: ${catalogue_view.context.getString(R.string.http_error_hint)}"
+            error.message!!.startsWith("HTTP error") -> "${error.message}: ${binding.catalogueView.context.getString(R.string.http_error_hint)}"
             else -> error.message!!
         }
     }
@@ -484,7 +480,7 @@ open class BrowseCatalogueController(bundle: Bundle) :
      * Shows the progress bar.
      */
     private fun showProgressBar() {
-        progress?.visible()
+        binding.progress.visible()
         snack?.dismiss()
         snack = null
     }
@@ -493,8 +489,8 @@ open class BrowseCatalogueController(bundle: Bundle) :
      * Hides active progress bars.
      */
     private fun hideProgressBar() {
-        empty_view.hide()
-        progress?.gone()
+        binding.emptyView.hide()
+        binding.progress.gone()
     }
 
     /**

+ 8 - 5
app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/global_search/CatalogueSearchController.kt

@@ -12,11 +12,11 @@ import androidx.recyclerview.widget.LinearLayoutManager
 import com.jakewharton.rxbinding.support.v7.widget.queryTextChangeEvents
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Manga
+import eu.kanade.tachiyomi.databinding.CatalogueGlobalSearchControllerBinding
 import eu.kanade.tachiyomi.source.CatalogueSource
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 import eu.kanade.tachiyomi.ui.manga.MangaController
-import kotlinx.android.synthetic.main.catalogue_global_search_controller.recycler
 
 /**
  * This controller shows and manages the different search result in global search.
@@ -34,6 +34,8 @@ open class CatalogueSearchController(
      */
     protected var adapter: CatalogueSearchAdapter? = null
 
+    private lateinit var binding: CatalogueGlobalSearchControllerBinding
+
     /**
      * Called when controller is initialized.
      */
@@ -48,8 +50,9 @@ open class CatalogueSearchController(
      * @param container containing parent views.
      * @return inflated view
      */
-    override fun inflateView(inflater: LayoutInflater, container: ViewGroup): android.view.View {
-        return inflater.inflate(R.layout.catalogue_global_search_controller, container, false)
+    override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
+        binding = CatalogueGlobalSearchControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     /**
@@ -136,8 +139,8 @@ open class CatalogueSearchController(
         adapter = CatalogueSearchAdapter(this)
 
         // Create recycler and set adapter.
-        recycler.layoutManager = LinearLayoutManager(view.context)
-        recycler.adapter = adapter
+        binding.recycler.layoutManager = LinearLayoutManager(view.context)
+        binding.recycler.adapter = adapter
     }
 
     override fun onDestroyView(view: View) {

+ 11 - 10
app/src/main/java/eu/kanade/tachiyomi/ui/category/CategoryController.kt

@@ -16,11 +16,9 @@ import eu.davidea.flexibleadapter.SelectableAdapter
 import eu.davidea.flexibleadapter.helpers.UndoHelper
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Category
+import eu.kanade.tachiyomi.databinding.CategoriesControllerBinding
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.util.system.toast
-import kotlinx.android.synthetic.main.categories_controller.empty_view
-import kotlinx.android.synthetic.main.categories_controller.fab
-import kotlinx.android.synthetic.main.categories_controller.recycler
 
 /**
  * Controller to manage the categories for the users' library.
@@ -49,6 +47,8 @@ class CategoryController : NucleusController<CategoryPresenter>(),
      */
     private var undoHelper: UndoHelper? = null
 
+    private lateinit var binding: CategoriesControllerBinding
+
     /**
      * Creates the presenter for this controller. Not to be manually called.
      */
@@ -68,7 +68,8 @@ class CategoryController : NucleusController<CategoryPresenter>(),
      * @param container The parent view for this one.
      */
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.categories_controller, container, false)
+        binding = CategoriesControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     /**
@@ -80,13 +81,13 @@ class CategoryController : NucleusController<CategoryPresenter>(),
         super.onViewCreated(view)
 
         adapter = CategoryAdapter(this@CategoryController)
-        recycler.layoutManager = LinearLayoutManager(view.context)
-        recycler.setHasFixedSize(true)
-        recycler.adapter = adapter
+        binding.recycler.layoutManager = LinearLayoutManager(view.context)
+        binding.recycler.setHasFixedSize(true)
+        binding.recycler.adapter = adapter
         adapter?.isHandleDragEnabled = true
         adapter?.isPermanentDelete = false
 
-        fab.clicks().subscribeUntilDestroy {
+        binding.fab.clicks().subscribeUntilDestroy {
             CategoryCreateDialog(this@CategoryController).showDialog(router, null)
         }
     }
@@ -114,13 +115,13 @@ class CategoryController : NucleusController<CategoryPresenter>(),
         actionMode?.finish()
         adapter?.updateDataSet(categories)
         if (categories.isNotEmpty()) {
-            empty_view.hide()
+            binding.emptyView.hide()
             val selected = categories.filter { it.isSelected }
             if (selected.isNotEmpty()) {
                 selected.forEach { onItemLongClick(categories.indexOf(it)) }
             }
         } else {
-            empty_view.show(R.string.information_empty_category)
+            binding.emptyView.show(R.string.information_empty_category)
         }
     }
 

+ 11 - 9
app/src/main/java/eu/kanade/tachiyomi/ui/download/DownloadController.kt

@@ -10,12 +10,11 @@ import androidx.recyclerview.widget.LinearLayoutManager
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.download.DownloadService
 import eu.kanade.tachiyomi.data.download.model.Download
+import eu.kanade.tachiyomi.databinding.DownloadControllerBinding
 import eu.kanade.tachiyomi.source.model.Page
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import java.util.HashMap
 import java.util.concurrent.TimeUnit
-import kotlinx.android.synthetic.main.download_controller.empty_view
-import kotlinx.android.synthetic.main.download_controller.recycler
 import rx.Observable
 import rx.Subscription
 import rx.android.schedulers.AndroidSchedulers
@@ -42,12 +41,15 @@ class DownloadController : NucleusController<DownloadPresenter>(),
      */
     private var isRunning: Boolean = false
 
+    private lateinit var binding: DownloadControllerBinding
+
     init {
         setHasOptionsMenu(true)
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.download_controller, container, false)
+        binding = DownloadControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun createPresenter(): DownloadPresenter {
@@ -66,12 +68,12 @@ class DownloadController : NucleusController<DownloadPresenter>(),
 
         // Initialize adapter.
         adapter = DownloadAdapter(this@DownloadController)
-        recycler.adapter = adapter
+        binding.recycler.adapter = adapter
         adapter?.isHandleDragEnabled = true
 
         // Set the layout manager for the recycler and fixed size.
-        recycler.layoutManager = LinearLayoutManager(view.context)
-        recycler.setHasFixedSize(true)
+        binding.recycler.layoutManager = LinearLayoutManager(view.context)
+        binding.recycler.setHasFixedSize(true)
 
         // Subscribe to changes
         DownloadService.runningRelay
@@ -242,7 +244,7 @@ class DownloadController : NucleusController<DownloadPresenter>(),
      * @return the holder of the download or null if it's not bound.
      */
     private fun getHolder(download: Download): DownloadHolder? {
-        return recycler?.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder
+        return binding.recycler.findViewHolderForItemId(download.chapter.id!!) as? DownloadHolder
     }
 
     /**
@@ -250,9 +252,9 @@ class DownloadController : NucleusController<DownloadPresenter>(),
      */
     private fun setInformationView() {
         if (presenter.downloadQueue.isEmpty()) {
-            empty_view?.show(R.string.information_no_downloads)
+            binding.emptyView.show(R.string.information_no_downloads)
         } else {
-            empty_view?.hide()
+            binding.emptyView.hide()
         }
     }
 

+ 12 - 9
app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt

@@ -19,11 +19,11 @@ import eu.davidea.flexibleadapter.items.IFlexible
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.data.preference.getOrDefault
+import eu.kanade.tachiyomi.databinding.ExtensionControllerBinding
 import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
 import eu.kanade.tachiyomi.extension.model.Extension
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
-import kotlinx.android.synthetic.main.extension_controller.*
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 
@@ -47,6 +47,8 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
 
     private var query = ""
 
+    private lateinit var binding: ExtensionControllerBinding
+
     init {
         setHasOptionsMenu(true)
     }
@@ -60,24 +62,25 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.extension_controller, container, false)
+        binding = ExtensionControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
 
-        ext_swipe_refresh.isRefreshing = true
-        ext_swipe_refresh.refreshes().subscribeUntilDestroy {
+        binding.extSwipeRefresh.isRefreshing = true
+        binding.extSwipeRefresh.refreshes().subscribeUntilDestroy {
             presenter.findAvailableExtensions()
         }
 
         // Initialize adapter, scroll listener and recycler views
         adapter = ExtensionAdapter(this)
         // Create recycler and set adapter.
-        ext_recycler.layoutManager = LinearLayoutManager(view.context)
-        ext_recycler.adapter = adapter
-        ext_recycler.addItemDecoration(ExtensionDividerItemDecoration(view.context))
-        adapter?.fastScroller = fast_scroller
+        binding.extRecycler.layoutManager = LinearLayoutManager(view.context)
+        binding.extRecycler.adapter = adapter
+        binding.extRecycler.addItemDecoration(ExtensionDividerItemDecoration(view.context))
+        adapter?.fastScroller = binding.fastScroller
     }
 
     override fun onDestroyView(view: View) {
@@ -184,7 +187,7 @@ open class ExtensionController : NucleusController<ExtensionPresenter>(),
     }
 
     fun setExtensions(extensions: List<ExtensionItem>) {
-        ext_swipe_refresh?.isRefreshing = false
+        binding.extSwipeRefresh.isRefreshing = false
         this.extensions = extensions
         drawExtensions()
     }

+ 16 - 22
app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt

@@ -26,21 +26,13 @@ import com.jakewharton.rxbinding.view.clicks
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.preference.EmptyPreferenceDataStore
 import eu.kanade.tachiyomi.data.preference.SharedPreferencesDataStore
+import eu.kanade.tachiyomi.databinding.ExtensionDetailControllerBinding
 import eu.kanade.tachiyomi.source.ConfigurableSource
 import eu.kanade.tachiyomi.source.Source
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.util.preference.preferenceCategory
 import eu.kanade.tachiyomi.util.system.LocaleHelper
 import eu.kanade.tachiyomi.util.view.visible
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_icon
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_lang
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_obsolete
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_pkg
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_prefs_empty_view
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_prefs_recycler
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_title
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_uninstall_button
-import kotlinx.android.synthetic.main.extension_detail_controller.extension_version
 
 @SuppressLint("RestrictedApi")
 class ExtensionDetailsController(bundle: Bundle? = null) :
@@ -52,14 +44,16 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
 
     private var preferenceScreen: PreferenceScreen? = null
 
+    private lateinit var binding: ExtensionDetailControllerBinding
+
     constructor(pkgName: String) : this(Bundle().apply {
         putString(PKGNAME_KEY, pkgName)
     })
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
         val themedInflater = inflater.cloneInContext(getPreferenceThemeContext())
-
-        return themedInflater.inflate(R.layout.extension_detail_controller, container, false)
+        binding = ExtensionDetailControllerBinding.inflate(themedInflater)
+        return binding.root
     }
 
     override fun createPresenter(): ExtensionDetailsPresenter {
@@ -77,17 +71,17 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
         val extension = presenter.extension ?: return
         val context = view.context
 
-        extension_title.text = extension.name
-        extension_version.text = context.getString(R.string.ext_version_info, extension.versionName)
-        extension_lang.text = context.getString(R.string.ext_language_info, LocaleHelper.getDisplayName(extension.lang, context))
-        extension_pkg.text = extension.pkgName
-        extension.getApplicationIcon(context)?.let { extension_icon.setImageDrawable(it) }
-        extension_uninstall_button.clicks().subscribeUntilDestroy {
+        binding.extensionTitle.text = extension.name
+        binding.extensionVersion.text = context.getString(R.string.ext_version_info, extension.versionName)
+        binding.extensionLang.text = context.getString(R.string.ext_language_info, LocaleHelper.getDisplayName(extension.lang, context))
+        binding.extensionPkg.text = extension.pkgName
+        extension.getApplicationIcon(context)?.let { binding.extensionIcon.setImageDrawable(it) }
+        binding.extensionUninstallButton.clicks().subscribeUntilDestroy {
             presenter.uninstallExtension()
         }
 
         if (extension.isObsolete) {
-            extension_obsolete.visible()
+            binding.extensionObsolete.visible()
         }
 
         val themedContext by lazy { getPreferenceThemeContext() }
@@ -107,12 +101,12 @@ class ExtensionDetailsController(bundle: Bundle? = null) :
 
         manager.setPreferences(screen)
 
-        extension_prefs_recycler.layoutManager = LinearLayoutManager(context)
-        extension_prefs_recycler.adapter = PreferenceGroupAdapter(screen)
-        extension_prefs_recycler.addItemDecoration(DividerItemDecoration(context, VERTICAL))
+        binding.extensionPrefsRecycler.layoutManager = LinearLayoutManager(context)
+        binding.extensionPrefsRecycler.adapter = PreferenceGroupAdapter(screen)
+        binding.extensionPrefsRecycler.addItemDecoration(DividerItemDecoration(context, VERTICAL))
 
         if (screen.preferenceCount == 0) {
-            extension_prefs_empty_view.show(R.string.ext_empty_preferences)
+            binding.extensionPrefsEmptyView.show(R.string.ext_empty_preferences)
         }
     }
 

+ 22 - 21
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt

@@ -29,6 +29,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.data.preference.getOrDefault
+import eu.kanade.tachiyomi.databinding.LibraryControllerBinding
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.base.controller.RootController
 import eu.kanade.tachiyomi.ui.base.controller.TabbedController
@@ -38,9 +39,6 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
 import eu.kanade.tachiyomi.util.system.getResourceColor
 import eu.kanade.tachiyomi.util.system.toast
 import java.io.IOException
-import kotlinx.android.synthetic.main.library_controller.action_toolbar
-import kotlinx.android.synthetic.main.library_controller.empty_view
-import kotlinx.android.synthetic.main.library_controller.library_pager
 import kotlinx.android.synthetic.main.main_activity.tabs
 import rx.Subscription
 import timber.log.Timber
@@ -127,6 +125,8 @@ class LibraryController(
 
     private var searchViewSubscription: Subscription? = null
 
+    private lateinit var binding: LibraryControllerBinding
+
     init {
         setHasOptionsMenu(true)
         retainViewMode = RetainViewMode.RETAIN_DETACH
@@ -141,15 +141,16 @@ class LibraryController(
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.library_controller, container, false)
+        binding = LibraryControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
 
         adapter = LibraryAdapter(this)
-        library_pager.adapter = adapter
-        library_pager.pageSelections().skip(1).subscribeUntilDestroy {
+        binding.libraryPager.adapter = adapter
+        binding.libraryPager.pageSelections().skip(1).subscribeUntilDestroy {
             preferences.lastUsedCategory().set(it)
             activeCategory = it
         }
@@ -177,14 +178,14 @@ class LibraryController(
     override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
         super.onChangeStarted(handler, type)
         if (type.isEnter) {
-            activity?.tabs?.setupWithViewPager(library_pager)
+            activity?.tabs?.setupWithViewPager(binding.libraryPager)
             presenter.subscribeLibrary()
         }
     }
 
     override fun onDestroyView(view: View) {
         destroyActionModeIfNeeded()
-        action_toolbar.destroy()
+        binding.actionToolbar.destroy()
         adapter?.onDestroy()
         adapter = null
         settingsSheet = null
@@ -224,14 +225,14 @@ class LibraryController(
 
         // Show empty view if needed
         if (mangaMap.isNotEmpty()) {
-            empty_view.hide()
+            binding.emptyView.hide()
         } else {
-            empty_view.show(R.string.information_empty_library)
+            binding.emptyView.show(R.string.information_empty_library)
         }
 
         // Get the current active category.
         val activeCat = if (adapter.categories.isNotEmpty())
-            library_pager.currentItem
+            binding.libraryPager.currentItem
         else
             activeCategory
 
@@ -239,14 +240,14 @@ class LibraryController(
         adapter.categories = categories
 
         // Restore active category.
-        library_pager.setCurrentItem(activeCat, false)
+        binding.libraryPager.setCurrentItem(activeCat, false)
 
         tabsVisibilityRelay.call(categories.size > 1)
 
         // Delay the scroll position to allow the view to be properly measured.
         view.post {
             if (isAttached) {
-                activity?.tabs?.setScrollPosition(library_pager.currentItem, 0f, true)
+                activity?.tabs?.setScrollPosition(binding.libraryPager.currentItem, 0f, true)
             }
         }
 
@@ -291,11 +292,11 @@ class LibraryController(
     private fun reattachAdapter() {
         val adapter = adapter ?: return
 
-        val position = library_pager.currentItem
+        val position = binding.libraryPager.currentItem
 
         adapter.recycle = false
-        library_pager.adapter = adapter
-        library_pager.currentItem = position
+        binding.libraryPager.adapter = adapter
+        binding.libraryPager.currentItem = position
         adapter.recycle = true
     }
 
@@ -305,7 +306,7 @@ class LibraryController(
     fun createActionModeIfNeeded() {
         if (actionMode == null) {
             actionMode = (activity as AppCompatActivity).startSupportActionMode(this)
-            action_toolbar.show(
+            binding.actionToolbar.show(
                     actionMode!!,
                     R.menu.library_selection
             ) { onActionItemClicked(actionMode!!, it!!) }
@@ -398,7 +399,7 @@ class LibraryController(
         } else {
             mode.title = count.toString()
 
-            action_toolbar.findItem(R.id.action_edit_cover)?.isVisible = count == 1
+            binding.actionToolbar.findItem(R.id.action_edit_cover)?.isVisible = count == 1
         }
         return false
     }
@@ -419,7 +420,7 @@ class LibraryController(
     }
 
     override fun onDestroyActionMode(mode: ActionMode?) {
-        action_toolbar.hide()
+        binding.actionToolbar.hide()
         // Clear all the manga selections and notify child views.
         selectedMangas.clear()
         selectionRelay.call(LibrarySelectionEvent.Cleared())
@@ -515,13 +516,13 @@ class LibraryController(
     }
 
     private fun selectAllCategoryManga() {
-        adapter?.categories?.getOrNull(library_pager.currentItem)?.id?.let {
+        adapter?.categories?.getOrNull(binding.libraryPager.currentItem)?.id?.let {
             selectAllRelay.call(it)
         }
     }
 
     private fun selectInverseCategoryManga() {
-        adapter?.categories?.getOrNull(library_pager.currentItem)?.id?.let {
+        adapter?.categories?.getOrNull(binding.libraryPager.currentItem)?.id?.let {
             selectInverseRelay.call(it)
         }
     }

+ 9 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

@@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.DatabaseHelper
 import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.track.TrackManager
+import eu.kanade.tachiyomi.databinding.MangaControllerBinding
 import eu.kanade.tachiyomi.source.Source
 import eu.kanade.tachiyomi.source.SourceManager
 import eu.kanade.tachiyomi.ui.base.controller.RxController
@@ -29,7 +30,6 @@ import eu.kanade.tachiyomi.ui.manga.track.TrackController
 import eu.kanade.tachiyomi.util.system.toast
 import java.util.Date
 import kotlinx.android.synthetic.main.main_activity.tabs
-import kotlinx.android.synthetic.main.manga_controller.manga_pager
 import rx.Subscription
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
@@ -68,6 +68,8 @@ class MangaController : RxController, TabbedController {
 
     val mangaFavoriteRelay: PublishRelay<Boolean> = PublishRelay.create()
 
+    private lateinit var binding: MangaControllerBinding
+
     private val trackingIconRelay: BehaviorRelay<Boolean> = BehaviorRelay.create()
 
     private var trackingIconSubscription: Subscription? = null
@@ -77,7 +79,8 @@ class MangaController : RxController, TabbedController {
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.manga_controller, container, false)
+        binding = MangaControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
@@ -88,11 +91,11 @@ class MangaController : RxController, TabbedController {
         requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301)
 
         adapter = MangaDetailAdapter()
-        manga_pager.offscreenPageLimit = 3
-        manga_pager.adapter = adapter
+        binding.mangaPager.offscreenPageLimit = 3
+        binding.mangaPager.adapter = adapter
 
         if (!fromCatalogue)
-            manga_pager.currentItem = CHAPTERS_CONTROLLER
+            binding.mangaPager.currentItem = CHAPTERS_CONTROLLER
     }
 
     override fun onDestroyView(view: View) {
@@ -103,7 +106,7 @@ class MangaController : RxController, TabbedController {
     override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
         super.onChangeStarted(handler, type)
         if (type.isEnter) {
-            activity?.tabs?.setupWithViewPager(manga_pager)
+            activity?.tabs?.setupWithViewPager(binding.mangaPager)
             trackingIconSubscription = trackingIconRelay.subscribe { setTrackingIconInternal(it) }
         }
     }

+ 34 - 36
app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt

@@ -24,6 +24,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Chapter
 import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.download.model.Download
+import eu.kanade.tachiyomi.databinding.ChaptersControllerBinding
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.base.controller.popControllerWithTag
 import eu.kanade.tachiyomi.ui.manga.MangaController
@@ -32,12 +33,6 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
 import eu.kanade.tachiyomi.util.system.toast
 import eu.kanade.tachiyomi.util.view.getCoordinates
 import eu.kanade.tachiyomi.util.view.snack
-import kotlinx.android.synthetic.main.chapters_controller.action_toolbar
-import kotlinx.android.synthetic.main.chapters_controller.fab
-import kotlinx.android.synthetic.main.chapters_controller.fast_scroller
-import kotlinx.android.synthetic.main.chapters_controller.recycler
-import kotlinx.android.synthetic.main.chapters_controller.reveal_view
-import kotlinx.android.synthetic.main.chapters_controller.swipe_refresh
 import timber.log.Timber
 
 class ChaptersController : NucleusController<ChaptersPresenter>(),
@@ -64,6 +59,8 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
 
     private var lastClickPosition = -1
 
+    private lateinit var binding: ChaptersControllerBinding
+
     init {
         setHasOptionsMenu(true)
         setOptionsMenuHidden(true)
@@ -76,7 +73,8 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.chapters_controller, container, false)
+        binding = ChaptersControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
@@ -85,15 +83,15 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
         // Init RecyclerView and adapter
         adapter = ChaptersAdapter(this, view.context)
 
-        recycler.adapter = adapter
-        recycler.layoutManager = LinearLayoutManager(view.context)
-        recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
-        recycler.setHasFixedSize(true)
-        adapter?.fastScroller = fast_scroller
+        binding.recycler.adapter = adapter
+        binding.recycler.layoutManager = LinearLayoutManager(view.context)
+        binding.recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
+        binding.recycler.setHasFixedSize(true)
+        adapter?.fastScroller = binding.fastScroller
 
-        swipe_refresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
+        binding.swipeRefresh.refreshes().subscribeUntilDestroy { fetchChaptersFromSource() }
 
-        fab.clicks().subscribeUntilDestroy {
+        binding.fab.clicks().subscribeUntilDestroy {
             val item = presenter.getNextUnreadChapter()
             if (item != null) {
                 // Create animation listener
@@ -104,8 +102,8 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
                 }
 
                 // Get coordinates and start animation
-                val coordinates = fab.getCoordinates()
-                if (!reveal_view.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
+                val coordinates = binding.fab.getCoordinates()
+                if (!binding.revealView.showRevealEffect(coordinates.x, coordinates.y, revealAnimationListener)) {
                     openChapter(item.chapter)
                 }
             } else {
@@ -116,7 +114,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
 
     override fun onDestroyView(view: View) {
         destroyActionModeIfNeeded()
-        action_toolbar.destroy()
+        binding.actionToolbar.destroy()
         adapter = null
         super.onDestroyView(view)
     }
@@ -125,10 +123,10 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
         if (view == null) return
 
         // Check if animation view is visible
-        if (reveal_view.visibility == View.VISIBLE) {
-            // Show the unReveal effect
-            val coordinates = fab.getCoordinates()
-            reveal_view.hideRevealEffect(coordinates.x, coordinates.y, 1920)
+        if (binding.revealView.visibility == View.VISIBLE) {
+            // Show the unreveal effect
+            val coordinates = binding.fab.getCoordinates()
+            binding.revealView.hideRevealEffect(coordinates.x, coordinates.y, 1920)
         }
         super.onActivityResumed(activity)
     }
@@ -267,16 +265,16 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
     }
 
     private fun fetchChaptersFromSource() {
-        swipe_refresh?.isRefreshing = true
+        binding.swipeRefresh.isRefreshing = true
         presenter.fetchChaptersFromSource()
     }
 
     fun onFetchChaptersDone() {
-        swipe_refresh?.isRefreshing = false
+        binding.swipeRefresh.isRefreshing = false
     }
 
     fun onFetchChaptersError(error: Throwable) {
-        swipe_refresh?.isRefreshing = false
+        binding.swipeRefresh.isRefreshing = false
         activity?.toast(error.message)
     }
 
@@ -285,7 +283,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
     }
 
     private fun getHolder(chapter: Chapter): ChapterHolder? {
-        return recycler?.findViewHolderForItemId(chapter.id!!) as? ChapterHolder
+        return binding.recycler.findViewHolderForItemId(chapter.id!!) as? ChapterHolder
     }
 
     fun openChapter(chapter: Chapter, hasAnimation: Boolean = false) {
@@ -357,7 +355,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
     private fun createActionModeIfNeeded() {
         if (actionMode == null) {
             actionMode = (activity as? AppCompatActivity)?.startSupportActionMode(this)
-            action_toolbar.show(
+            binding.actionToolbar.show(
                     actionMode!!,
                     R.menu.chapter_selection
             ) { onActionItemClicked(actionMode!!, it!!) }
@@ -384,15 +382,15 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
             mode.title = count.toString()
 
             val chapters = getSelectedChapters()
-            action_toolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded }
-            action_toolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded }
-            action_toolbar.findItem(R.id.action_bookmark)?.isVisible = chapters.any { !it.chapter.bookmark }
-            action_toolbar.findItem(R.id.action_remove_bookmark)?.isVisible = chapters.all { it.chapter.bookmark }
-            action_toolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read }
-            action_toolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read }
+            binding.actionToolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded }
+            binding.actionToolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded }
+            binding.actionToolbar.findItem(R.id.action_bookmark)?.isVisible = chapters.any { !it.chapter.bookmark }
+            binding.actionToolbar.findItem(R.id.action_remove_bookmark)?.isVisible = chapters.all { it.chapter.bookmark }
+            binding.actionToolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read }
+            binding.actionToolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read }
 
             // Hide FAB to avoid interfering with the bottom action toolbar
-            fab.hide()
+            binding.fab.hide()
         }
         return false
     }
@@ -414,13 +412,13 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
     }
 
     override fun onDestroyActionMode(mode: ActionMode) {
-        action_toolbar.hide()
+        binding.actionToolbar.hide()
         adapter?.mode = SelectableAdapter.Mode.SINGLE
         adapter?.clearSelection()
         selectedItems.clear()
         actionMode = null
 
-        fab.show()
+        binding.fab.show()
     }
 
     override fun onDetach(view: View) {
@@ -461,7 +459,7 @@ class ChaptersController : NucleusController<ChaptersPresenter>(),
         val view = view
         presenter.downloadChapters(chapters)
         if (view != null && !presenter.manga.favorite) {
-            recycler?.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) {
+            binding.recycler.snack(view.context.getString(R.string.snack_add_to_library), Snackbar.LENGTH_INDEFINITE) {
                 setAction(R.string.action_add) {
                     presenter.addToLibrary()
                 }

+ 41 - 54
app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoController.kt

@@ -36,6 +36,7 @@ import eu.kanade.tachiyomi.data.glide.GlideApp
 import eu.kanade.tachiyomi.data.notification.NotificationReceiver
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.data.preference.getOrDefault
+import eu.kanade.tachiyomi.databinding.MangaInfoControllerBinding
 import eu.kanade.tachiyomi.source.Source
 import eu.kanade.tachiyomi.source.SourceManager
 import eu.kanade.tachiyomi.source.model.SManga
@@ -57,20 +58,6 @@ import java.text.DateFormat
 import java.text.DecimalFormat
 import java.util.Date
 import jp.wasabeef.glide.transformations.CropSquareTransformation
-import kotlinx.android.synthetic.main.manga_info_controller.backdrop
-import kotlinx.android.synthetic.main.manga_info_controller.fab_favorite
-import kotlinx.android.synthetic.main.manga_info_controller.manga_artist
-import kotlinx.android.synthetic.main.manga_info_controller.manga_artist_label
-import kotlinx.android.synthetic.main.manga_info_controller.manga_author
-import kotlinx.android.synthetic.main.manga_info_controller.manga_chapters
-import kotlinx.android.synthetic.main.manga_info_controller.manga_cover
-import kotlinx.android.synthetic.main.manga_info_controller.manga_full_title
-import kotlinx.android.synthetic.main.manga_info_controller.manga_genres_tags
-import kotlinx.android.synthetic.main.manga_info_controller.manga_last_update
-import kotlinx.android.synthetic.main.manga_info_controller.manga_source
-import kotlinx.android.synthetic.main.manga_info_controller.manga_status
-import kotlinx.android.synthetic.main.manga_info_controller.manga_summary
-import kotlinx.android.synthetic.main.manga_info_controller.swipe_refresh
 import uy.kohesive.injekt.Injekt
 import uy.kohesive.injekt.api.get
 import uy.kohesive.injekt.injectLazy
@@ -83,15 +70,14 @@ import uy.kohesive.injekt.injectLazy
 class MangaInfoController : NucleusController<MangaInfoPresenter>(),
         ChangeMangaCategoriesDialog.Listener {
 
-    /**
-     * Preferences helper.
-     */
     private val preferences: PreferencesHelper by injectLazy()
 
     private val dateFormat: DateFormat by lazy {
         preferences.dateFormat().getOrDefault()
     }
 
+    private lateinit var binding: MangaInfoControllerBinding
+
     init {
         setHasOptionsMenu(true)
         setOptionsMenuHidden(true)
@@ -104,50 +90,51 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.manga_info_controller, container, false)
+        binding = MangaInfoControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
 
         // Set onclickListener to toggle favorite when FAB clicked.
-        fab_favorite.clicks().subscribeUntilDestroy { onFabClick() }
+        binding.fabFavorite.clicks().subscribeUntilDestroy { onFabClick() }
 
         // Set onLongClickListener to manage categories when FAB is clicked.
-        fab_favorite.longClicks().subscribeUntilDestroy { onFabLongClick() }
+        binding.fabFavorite.longClicks().subscribeUntilDestroy { onFabLongClick() }
 
         // Set SwipeRefresh to refresh manga data.
-        swipe_refresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() }
+        binding.swipeRefresh.refreshes().subscribeUntilDestroy { fetchMangaFromSource() }
 
-        manga_full_title.longClicks().subscribeUntilDestroy {
-            copyToClipboard(view.context.getString(R.string.title), manga_full_title.text.toString())
+        binding.mangaFullTitle.longClicks().subscribeUntilDestroy {
+            copyToClipboard(view.context.getString(R.string.title), binding.mangaFullTitle.text.toString())
         }
 
-        manga_full_title.clicks().subscribeUntilDestroy {
-            performGlobalSearch(manga_full_title.text.toString())
+        binding.mangaFullTitle.clicks().subscribeUntilDestroy {
+            performGlobalSearch(binding.mangaFullTitle.text.toString())
         }
 
-        manga_artist.longClicks().subscribeUntilDestroy {
-            copyToClipboard(manga_artist_label.text.toString(), manga_artist.text.toString())
+        binding.mangaArtist.longClicks().subscribeUntilDestroy {
+            copyToClipboard(binding.mangaArtistLabel.text.toString(), binding.mangaArtist.text.toString())
         }
 
-        manga_artist.clicks().subscribeUntilDestroy {
-            performGlobalSearch(manga_artist.text.toString())
+        binding.mangaArtist.clicks().subscribeUntilDestroy {
+            performGlobalSearch(binding.mangaArtist.text.toString())
         }
 
-        manga_author.longClicks().subscribeUntilDestroy {
-            copyToClipboard(manga_author.text.toString(), manga_author.text.toString())
+        binding.mangaAuthor.longClicks().subscribeUntilDestroy {
+            copyToClipboard(binding.mangaAuthor.text.toString(), binding.mangaAuthor.text.toString())
         }
 
-        manga_author.clicks().subscribeUntilDestroy {
-            performGlobalSearch(manga_author.text.toString())
+        binding.mangaAuthor.clicks().subscribeUntilDestroy {
+            performGlobalSearch(binding.mangaAuthor.text.toString())
         }
 
-        manga_summary.longClicks().subscribeUntilDestroy {
-            copyToClipboard(view.context.getString(R.string.description), manga_summary.text.toString())
+        binding.mangaSummary.longClicks().subscribeUntilDestroy {
+            copyToClipboard(view.context.getString(R.string.description), binding.mangaSummary.text.toString())
         }
 
-        manga_cover.longClicks().subscribeUntilDestroy {
+        binding.mangaCover.longClicks().subscribeUntilDestroy {
             copyToClipboard(view.context.getString(R.string.title), presenter.manga.title)
         }
     }
@@ -197,21 +184,21 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
         val view = view ?: return
 
         // update full title TextView.
-        manga_full_title.text = if (manga.title.isBlank()) {
+        binding.mangaFullTitle.text = if (manga.title.isBlank()) {
             view.context.getString(R.string.unknown)
         } else {
             manga.title
         }
 
         // Update artist TextView.
-        manga_artist.text = if (manga.artist.isNullOrBlank()) {
+        binding.mangaArtist.text = if (manga.artist.isNullOrBlank()) {
             view.context.getString(R.string.unknown)
         } else {
             manga.artist
         }
 
         // Update author TextView.
-        manga_author.text = if (manga.author.isNullOrBlank()) {
+        binding.mangaAuthor.text = if (manga.author.isNullOrBlank()) {
             view.context.getString(R.string.unknown)
         } else {
             manga.author
@@ -219,7 +206,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
 
         // If manga source is known update source TextView.
         val mangaSource = source?.toString()
-        with(manga_source) {
+        with(binding.mangaSource) {
             if (mangaSource != null) {
                 text = mangaSource
                 setOnClickListener {
@@ -233,7 +220,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
 
         // Update genres list
         if (!manga.genre.isNullOrBlank()) {
-            manga_genres_tags.removeAllViews()
+            binding.mangaGenresTags.removeAllViews()
 
             manga.genre?.split(", ")?.forEach { genre ->
                 val chip = Chip(view.context).apply {
@@ -241,19 +228,19 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
                     setOnClickListener { performSearch(genre) }
                 }
 
-                manga_genres_tags.addView(chip)
+                binding.mangaGenresTags.addView(chip)
             }
         }
 
         // Update description TextView.
-        manga_summary.text = if (manga.description.isNullOrBlank()) {
+        binding.mangaSummary.text = if (manga.description.isNullOrBlank()) {
             view.context.getString(R.string.unknown)
         } else {
             manga.description
         }
 
         // Update status TextView.
-        manga_status.setText(when (manga.status) {
+        binding.mangaStatus.setText(when (manga.status) {
             SManga.ONGOING -> R.string.ongoing
             SManga.COMPLETED -> R.string.completed
             SManga.LICENSED -> R.string.licensed
@@ -264,19 +251,19 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
         setFavoriteDrawable(manga.favorite)
 
         // Set cover if it wasn't already.
-        if (manga_cover.drawable == null && !manga.thumbnail_url.isNullOrEmpty()) {
+        if (binding.mangaCover.drawable == null && !manga.thumbnail_url.isNullOrEmpty()) {
             GlideApp.with(view.context)
                     .load(manga)
                     .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
                     .centerCrop()
-                    .into(manga_cover)
+                    .into(binding.mangaCover)
 
-            if (backdrop != null) {
+            if (binding.backdrop != null) {
                 GlideApp.with(view.context)
                         .load(manga)
                         .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
                         .centerCrop()
-                        .into(backdrop)
+                        .into(binding.backdrop!!)
             }
         }
     }
@@ -288,17 +275,17 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
      */
     fun setChapterCount(count: Float) {
         if (count > 0f) {
-            manga_chapters?.text = DecimalFormat("#.#").format(count)
+            binding.mangaChapters.text = DecimalFormat("#.#").format(count)
         } else {
-            manga_chapters?.text = resources?.getString(R.string.unknown)
+            binding.mangaChapters.text = resources?.getString(R.string.unknown)
         }
     }
 
     fun setLastUpdateDate(date: Date) {
         if (date.time != 0L) {
-            manga_last_update?.text = dateFormat.format(date)
+            binding.mangaLastUpdate.text = dateFormat.format(date)
         } else {
-            manga_last_update?.text = resources?.getString(R.string.unknown)
+            binding.mangaLastUpdate.text = resources?.getString(R.string.unknown)
         }
     }
 
@@ -359,7 +346,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
     private fun setFavoriteDrawable(isFavorite: Boolean) {
         // Set the Favorite drawable to the correct one.
         // Border drawable if false, filled drawable if true.
-        fab_favorite?.setImageResource(if (isFavorite)
+        binding.fabFavorite.setImageResource(if (isFavorite)
             R.drawable.ic_bookmark_24dp
         else
             R.drawable.ic_add_to_library_24dp)
@@ -395,7 +382,7 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
      * @param value whether it should be refreshing or not.
      */
     private fun setRefreshing(value: Boolean) {
-        swipe_refresh?.isRefreshing = value
+        binding.swipeRefresh.isRefreshing = value
     }
 
     private fun onFabClick() {

+ 15 - 15
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackController.kt

@@ -9,11 +9,10 @@ import androidx.recyclerview.widget.LinearLayoutManager
 import com.jakewharton.rxbinding.support.v4.widget.refreshes
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.track.model.TrackSearch
+import eu.kanade.tachiyomi.databinding.TrackControllerBinding
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.manga.MangaController
 import eu.kanade.tachiyomi.util.system.toast
-import kotlinx.android.synthetic.main.track_controller.swipe_refresh
-import kotlinx.android.synthetic.main.track_controller.track_recycler
 import timber.log.Timber
 
 class TrackController : NucleusController<TrackPresenter>(),
@@ -24,6 +23,8 @@ class TrackController : NucleusController<TrackPresenter>(),
 
     private var adapter: TrackAdapter? = null
 
+    private lateinit var binding: TrackControllerBinding
+
     init {
         // There's no menu, but this avoids a bug when coming from the catalogue, where the menu
         // disappears if the searchview is expanded
@@ -35,19 +36,18 @@ class TrackController : NucleusController<TrackPresenter>(),
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.track_controller, container, false)
+        binding = TrackControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
 
         adapter = TrackAdapter(this)
-        with(view) {
-            track_recycler.layoutManager = LinearLayoutManager(context)
-            track_recycler.adapter = adapter
-            swipe_refresh.isEnabled = false
-            swipe_refresh.refreshes().subscribeUntilDestroy { presenter.refresh() }
-        }
+        binding.trackRecycler.layoutManager = LinearLayoutManager(view.context)
+        binding.trackRecycler.adapter = adapter
+        binding.swipeRefresh.isEnabled = false
+        binding.swipeRefresh.refreshes().subscribeUntilDestroy { presenter.refresh() }
     }
 
     override fun onDestroyView(view: View) {
@@ -58,7 +58,7 @@ class TrackController : NucleusController<TrackPresenter>(),
     fun onNextTrackings(trackings: List<TrackItem>) {
         val atLeastOneLink = trackings.any { it.track != null }
         adapter?.items = trackings
-        swipe_refresh?.isEnabled = atLeastOneLink
+        binding.swipeRefresh.isEnabled = atLeastOneLink
         (parentController as? MangaController)?.setTrackingIcon(atLeastOneLink)
     }
 
@@ -77,11 +77,11 @@ class TrackController : NucleusController<TrackPresenter>(),
     }
 
     fun onRefreshDone() {
-        swipe_refresh?.isRefreshing = false
+        binding.swipeRefresh.isRefreshing = false
     }
 
     fun onRefreshError(error: Throwable) {
-        swipe_refresh?.isRefreshing = false
+        binding.swipeRefresh.isRefreshing = false
         activity?.toast(error.message)
     }
 
@@ -123,17 +123,17 @@ class TrackController : NucleusController<TrackPresenter>(),
 
     override fun setStatus(item: TrackItem, selection: Int) {
         presenter.setStatus(item, selection)
-        swipe_refresh?.isRefreshing = true
+        binding.swipeRefresh.isRefreshing = true
     }
 
     override fun setScore(item: TrackItem, score: Int) {
         presenter.setScore(item, score)
-        swipe_refresh?.isRefreshing = true
+        binding.swipeRefresh.isRefreshing = true
     }
 
     override fun setChaptersRead(item: TrackItem, chaptersRead: Int) {
         presenter.setLastChapterRead(item, chaptersRead)
-        swipe_refresh?.isRefreshing = true
+        binding.swipeRefresh.isRefreshing = true
     }
 
     private companion object {

+ 9 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/migration/MigrationController.kt

@@ -7,9 +7,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
 import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.davidea.flexibleadapter.items.IFlexible
 import eu.kanade.tachiyomi.R
+import eu.kanade.tachiyomi.databinding.MigrationControllerBinding
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
-import kotlinx.android.synthetic.main.migration_controller.migration_recycler
 
 class MigrationController : NucleusController<MigrationPresenter>(),
         FlexibleAdapter.OnItemClickListener,
@@ -23,20 +23,23 @@ class MigrationController : NucleusController<MigrationPresenter>(),
             setTitle()
         }
 
+    private lateinit var binding: MigrationControllerBinding
+
     override fun createPresenter(): MigrationPresenter {
         return MigrationPresenter()
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.migration_controller, container, false)
+        binding = MigrationControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
 
         adapter = FlexibleAdapter(null, this)
-        migration_recycler.layoutManager = LinearLayoutManager(view.context)
-        migration_recycler.adapter = adapter
+        binding.migrationRecycler.layoutManager = LinearLayoutManager(view.context)
+        binding.migrationRecycler.adapter = adapter
     }
 
     override fun onDestroyView(view: View) {
@@ -62,14 +65,14 @@ class MigrationController : NucleusController<MigrationPresenter>(),
             title = resources?.getString(R.string.label_migration)
             if (adapter !is SourceAdapter) {
                 adapter = SourceAdapter(this)
-                migration_recycler.adapter = adapter
+                binding.migrationRecycler.adapter = adapter
             }
             adapter?.updateDataSet(state.sourcesWithManga)
         } else {
             title = state.selectedSource.toString()
             if (adapter !is MangaAdapter) {
                 adapter = MangaAdapter(this)
-                migration_recycler.adapter = adapter
+                binding.migrationRecycler.adapter = adapter
             }
             adapter?.updateDataSet(state.mangaForSource)
         }

+ 0 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -84,9 +84,6 @@ import uy.kohesive.injekt.injectLazy
 @RequiresPresenter(ReaderPresenter::class)
 class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
 
-    /**
-     * Preferences helper.
-     */
     private val preferences by injectLazy<PreferencesHelper>()
 
     /**

+ 0 - 3
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderSettingsSheet.kt

@@ -38,9 +38,6 @@ import uy.kohesive.injekt.injectLazy
  */
 class ReaderSettingsSheet(private val activity: ReaderActivity) : BottomSheetDialog(activity) {
 
-    /**
-     * Preferences helper.
-     */
     private val preferences by injectLazy<PreferencesHelper>()
 
     init {

+ 10 - 8
app/src/main/java/eu/kanade/tachiyomi/ui/recent/history/HistoryController.kt

@@ -8,6 +8,7 @@ import eu.davidea.flexibleadapter.FlexibleAdapter
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.History
 import eu.kanade.tachiyomi.data.database.models.Manga
+import eu.kanade.tachiyomi.databinding.HistoryControllerBinding
 import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.base.controller.RootController
@@ -15,8 +16,6 @@ import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
 import eu.kanade.tachiyomi.ui.manga.MangaController
 import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 import eu.kanade.tachiyomi.util.system.toast
-import kotlinx.android.synthetic.main.history_controller.empty_view
-import kotlinx.android.synthetic.main.history_controller.recycler
 
 /**
  * Fragment that shows recently read manga.
@@ -38,6 +37,8 @@ class HistoryController : NucleusController<HistoryPresenter>(),
     var adapter: HistoryAdapter? = null
         private set
 
+    private lateinit var binding: HistoryControllerBinding
+
     override fun getTitle(): String? {
         return resources?.getString(R.string.label_recent_manga)
     }
@@ -47,7 +48,8 @@ class HistoryController : NucleusController<HistoryPresenter>(),
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.history_controller, container, false)
+        binding = HistoryControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     /**
@@ -59,10 +61,10 @@ class HistoryController : NucleusController<HistoryPresenter>(),
         super.onViewCreated(view)
 
         // Initialize adapter
-        recycler.layoutManager = LinearLayoutManager(view.context)
+        binding.recycler.layoutManager = LinearLayoutManager(view.context)
         adapter = HistoryAdapter(this@HistoryController)
-        recycler.setHasFixedSize(true)
-        recycler.adapter = adapter
+        binding.recycler.setHasFixedSize(true)
+        binding.recycler.adapter = adapter
     }
 
     override fun onDestroyView(view: View) {
@@ -81,9 +83,9 @@ class HistoryController : NucleusController<HistoryPresenter>(),
 
     override fun onUpdateEmptyView(size: Int) {
         if (size > 0) {
-            empty_view.hide()
+            binding.emptyView.hide()
         } else {
-            empty_view.show(R.string.information_no_recent_manga)
+            binding.emptyView.show(R.string.information_no_recent_manga)
         }
     }
 

+ 25 - 24
app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt

@@ -19,6 +19,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.download.model.Download
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService
 import eu.kanade.tachiyomi.data.notification.Notifications
+import eu.kanade.tachiyomi.databinding.UpdatesControllerBinding
 import eu.kanade.tachiyomi.ui.base.controller.NoToolbarElevationController
 import eu.kanade.tachiyomi.ui.base.controller.NucleusController
 import eu.kanade.tachiyomi.ui.base.controller.RootController
@@ -28,10 +29,6 @@ import eu.kanade.tachiyomi.ui.manga.MangaController
 import eu.kanade.tachiyomi.ui.reader.ReaderActivity
 import eu.kanade.tachiyomi.util.system.notificationManager
 import eu.kanade.tachiyomi.util.system.toast
-import kotlinx.android.synthetic.main.updates_controller.action_toolbar
-import kotlinx.android.synthetic.main.updates_controller.empty_view
-import kotlinx.android.synthetic.main.updates_controller.recycler
-import kotlinx.android.synthetic.main.updates_controller.swipe_refresh
 import timber.log.Timber
 
 /**
@@ -60,6 +57,8 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
     var adapter: UpdatesAdapter? = null
         private set
 
+    private lateinit var binding: UpdatesControllerBinding
+
     init {
         setHasOptionsMenu(true)
     }
@@ -73,7 +72,8 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
     }
 
     override fun inflateView(inflater: LayoutInflater, container: ViewGroup): View {
-        return inflater.inflate(R.layout.updates_controller, container, false)
+        binding = UpdatesControllerBinding.inflate(inflater)
+        return binding.root
     }
 
     /**
@@ -83,32 +83,33 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
     override fun onViewCreated(view: View) {
         super.onViewCreated(view)
         view.context.notificationManager.cancel(Notifications.ID_NEW_CHAPTERS)
+
         // Init RecyclerView and adapter
         val layoutManager = LinearLayoutManager(view.context)
-        recycler.layoutManager = layoutManager
-        recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
-        recycler.setHasFixedSize(true)
+        binding.recycler.layoutManager = layoutManager
+        binding.recycler.addItemDecoration(DividerItemDecoration(view.context, DividerItemDecoration.VERTICAL))
+        binding.recycler.setHasFixedSize(true)
         adapter = UpdatesAdapter(this@UpdatesController)
-        recycler.adapter = adapter
+        binding.recycler.adapter = adapter
 
-        recycler.scrollStateChanges().subscribeUntilDestroy {
+        binding.recycler.scrollStateChanges().subscribeUntilDestroy {
             // Disable swipe refresh when view is not at the top
             val firstPos = layoutManager.findFirstCompletelyVisibleItemPosition()
-            swipe_refresh.isEnabled = firstPos <= 0
+            binding.swipeRefresh.isEnabled = firstPos <= 0
         }
 
-        swipe_refresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
-        swipe_refresh.refreshes().subscribeUntilDestroy {
+        binding.swipeRefresh.setDistanceToTriggerSync((2 * 64 * view.resources.displayMetrics.density).toInt())
+        binding.swipeRefresh.refreshes().subscribeUntilDestroy {
             updateLibrary()
 
             // It can be a very long operation, so we disable swipe refresh and show a toast.
-            swipe_refresh.isRefreshing = false
+            binding.swipeRefresh.isRefreshing = false
         }
     }
 
     override fun onDestroyView(view: View) {
         destroyActionModeIfNeeded()
-        action_toolbar.destroy()
+        binding.actionToolbar.destroy()
         adapter = null
         super.onDestroyView(view)
     }
@@ -167,7 +168,7 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
     override fun onItemLongClick(position: Int) {
         if (actionMode == null) {
             actionMode = (activity as AppCompatActivity).startSupportActionMode(this)
-            action_toolbar.show(
+            binding.actionToolbar.show(
                     actionMode!!,
                     R.menu.updates_chapter_selection
             ) { onActionItemClicked(actionMode!!, it!!) }
@@ -215,9 +216,9 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
 
     override fun onUpdateEmptyView(size: Int) {
         if (size > 0) {
-            empty_view?.hide()
+            binding.emptyView.hide()
         } else {
-            empty_view?.show(R.string.information_no_recent)
+            binding.emptyView.show(R.string.information_no_recent)
         }
     }
 
@@ -234,7 +235,7 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
      * @param download [Download] object containing download progress.
      */
     private fun getHolder(download: Download): UpdatesHolder? {
-        return recycler?.findViewHolderForItemId(download.chapter.id!!) as? UpdatesHolder
+        return binding.recycler.findViewHolderForItemId(download.chapter.id!!) as? UpdatesHolder
     }
 
     /**
@@ -321,10 +322,10 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
             mode.title = count.toString()
 
             val chapters = getSelectedChapters()
-            action_toolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded }
-            action_toolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded }
-            action_toolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read }
-            action_toolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read }
+            binding.actionToolbar.findItem(R.id.action_download)?.isVisible = chapters.any { !it.isDownloaded }
+            binding.actionToolbar.findItem(R.id.action_delete)?.isVisible = chapters.any { it.isDownloaded }
+            binding.actionToolbar.findItem(R.id.action_mark_as_read)?.isVisible = chapters.any { !it.chapter.read }
+            binding.actionToolbar.findItem(R.id.action_mark_as_unread)?.isVisible = chapters.all { it.chapter.read }
         }
 
         return false
@@ -354,7 +355,7 @@ class UpdatesController : NucleusController<UpdatesPresenter>(),
      * @param mode the ActionMode object
      */
     override fun onDestroyActionMode(mode: ActionMode?) {
-        action_toolbar.hide()
+        binding.actionToolbar.hide()
         adapter?.mode = SelectableAdapter.Mode.IDLE
         adapter?.clearSelection()
         actionMode = null

+ 0 - 6
app/src/main/java/eu/kanade/tachiyomi/util/system/LocaleHelper.kt

@@ -16,14 +16,8 @@ import uy.kohesive.injekt.injectLazy
 @Suppress("DEPRECATION")
 object LocaleHelper {
 
-    /**
-     * Preferences helper.
-     */
     private val preferences: PreferencesHelper by injectLazy()
 
-    /**
-     * The system's locale.
-     */
     private var systemLocale: Locale? = null
 
     /**