Skip to content

Migrate from Kotlin synthetics to Jetpack view binding #5546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apply from: '../gitutils.gradle'
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-parcelize'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'kotlin-android-extensions' is deprecated so we're removing it in place of view binding instead.

We use parcelize, which is part of the old extensions plugin. It's now been moved out to its own plugin, hence we're adding that one back in. From from https://developer.android.com/topic/libraries/view-binding/migration:

Note: If your app uses Parcelable features, switch to using the standalone kotlin-parcelize Gradle plugin described in Parcelable implementation generator.

apply from: "$rootDir/jacoco.gradle"

def isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file('../play.p12').exists()
Expand Down Expand Up @@ -357,6 +357,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}

buildToolsVersion buildToolsVersion

Expand Down Expand Up @@ -397,7 +400,3 @@ if (isRunningOnTravisAndIsNotPRBuild) {
}
}
}

androidExtensions {
experimental = true
}
2 changes: 1 addition & 1 deletion app/src/main/java/fr/free/nrw/commons/Media.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package fr.free.nrw.commons

import android.os.Parcelable
import fr.free.nrw.commons.location.LatLng
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import fr.free.nrw.commons.wikidata.model.page.PageTitle
import java.util.*

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fr.free.nrw.commons.category

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize

@Parcelize
data class CategoryItem(val name: String, val description: String?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import fr.free.nrw.commons.upload.UploadMediaDetail
import fr.free.nrw.commons.upload.WikidataPlace
import fr.free.nrw.commons.upload.WikidataPlace.Companion.from
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import java.util.*

@Entity(tableName = "contribution")
Expand Down
58 changes: 28 additions & 30 deletions app/src/main/java/fr/free/nrw/commons/edit/EditActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import android.animation.ValueAnimator
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.graphics.drawable.BitmapDrawable
import android.media.ExifInterface
import android.os.Bundle
import android.util.Log
Expand All @@ -18,10 +17,7 @@ import androidx.core.graphics.rotationMatrix
import androidx.core.graphics.scaleMatrix
import androidx.core.net.toUri
import androidx.lifecycle.ViewModelProvider
import fr.free.nrw.commons.R
import kotlinx.android.synthetic.main.activity_edit.btn_save
import kotlinx.android.synthetic.main.activity_edit.iv
import kotlinx.android.synthetic.main.activity_edit.rotate_btn
import fr.free.nrw.commons.databinding.ActivityEditBinding
import timber.log.Timber
import java.io.File

Expand All @@ -37,10 +33,12 @@ class EditActivity : AppCompatActivity() {
private var imageUri = ""
private lateinit var vm: EditViewModel
private val sourceExifAttributeList = mutableListOf<Pair<String, String?>>()
private lateinit var binding: ActivityEditBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit)
binding = ActivityEditBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.title = ""
val intent = intent
imageUri = intent.getStringExtra("image") ?: ""
Expand Down Expand Up @@ -87,9 +85,9 @@ class EditActivity : AppCompatActivity() {
* for the "Rotate" and "Save" buttons.
*/
private fun init() {
iv.adjustViewBounds = true
iv.scaleType = ImageView.ScaleType.MATRIX
iv.post(Runnable {
binding.iv.adjustViewBounds = true
binding.iv.scaleType = ImageView.ScaleType.MATRIX
binding.iv.post(Runnable {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(imageUri, options)
Expand All @@ -104,26 +102,26 @@ class EditActivity : AppCompatActivity() {
options.inSampleSize = scaleFactor
options.inJustDecodeBounds = false
val scaledBitmap = BitmapFactory.decodeFile(imageUri, options)
iv.setImageBitmap(scaledBitmap)
binding.iv.setImageBitmap(scaledBitmap)
// Update the ImageView with the scaled bitmap
val scale = iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat()
iv.layoutParams.height = (scale * scaledBitmap.height).toInt()
iv.imageMatrix = scaleMatrix(scale, scale)
val scale = binding.iv.measuredWidth.toFloat() / scaledBitmap.width.toFloat()
binding.iv.layoutParams.height = (scale * scaledBitmap.height).toInt()
binding.iv.imageMatrix = scaleMatrix(scale, scale)
} else {

options.inJustDecodeBounds = false
val bitmap = BitmapFactory.decodeFile(imageUri, options)
iv.setImageBitmap(bitmap)
binding.iv.setImageBitmap(bitmap)

val scale = iv.measuredWidth.toFloat() / bitmapWidth.toFloat()
iv.layoutParams.height = (scale * bitmapHeight).toInt()
iv.imageMatrix = scaleMatrix(scale, scale)
val scale = binding.iv.measuredWidth.toFloat() / bitmapWidth.toFloat()
binding.iv.layoutParams.height = (scale * bitmapHeight).toInt()
binding.iv.imageMatrix = scaleMatrix(scale, scale)
}
})
rotate_btn.setOnClickListener {
binding.rotateBtn.setOnClickListener {
animateImageHeight()
}
btn_save.setOnClickListener {
binding.btnSave.setOnClickListener {
getRotatedImage()
}
}
Expand All @@ -140,10 +138,10 @@ class EditActivity : AppCompatActivity() {
* further rotation actions.
*/
private fun animateImageHeight() {
val drawableWidth: Float = iv.getDrawable().getIntrinsicWidth().toFloat()
val drawableHeight: Float = iv.getDrawable().getIntrinsicHeight().toFloat()
val viewWidth: Float = iv.getMeasuredWidth().toFloat()
val viewHeight: Float = iv.getMeasuredHeight().toFloat()
val drawableWidth: Float = binding.iv.getDrawable().getIntrinsicWidth().toFloat()
val drawableHeight: Float = binding.iv.getDrawable().getIntrinsicHeight().toFloat()
val viewWidth: Float = binding.iv.getMeasuredWidth().toFloat()
val viewHeight: Float = binding.iv.getMeasuredHeight().toFloat()
val rotation = imageRotation % 360
val newRotation = rotation + 90

Expand Down Expand Up @@ -173,12 +171,12 @@ class EditActivity : AppCompatActivity() {

animator.addListener(object : AnimatorListener {
override fun onAnimationStart(animation: Animator) {
rotate_btn.setEnabled(false)
binding.rotateBtn.setEnabled(false)
}

override fun onAnimationEnd(animation: Animator) {
imageRotation = newRotation % 360
rotate_btn.setEnabled(true)
binding.rotateBtn.setEnabled(true)
}

override fun onAnimationCancel(animation: Animator) {
Expand All @@ -196,7 +194,7 @@ class EditActivity : AppCompatActivity() {
(complementaryAnimVal * viewHeight + animVal * newViewHeight).toInt()
val animatedScale = complementaryAnimVal * imageScale + animVal * newImageScale
val animatedRotation = complementaryAnimVal * rotation + animVal * newRotation
iv.getLayoutParams().height = animatedHeight
binding.iv.getLayoutParams().height = animatedHeight
val matrix: Matrix = rotationMatrix(
animatedRotation,
drawableWidth / 2,
Expand All @@ -209,11 +207,11 @@ class EditActivity : AppCompatActivity() {
drawableHeight / 2
)
matrix.postTranslate(
-(drawableWidth - iv.getMeasuredWidth()) / 2,
-(drawableHeight - iv.getMeasuredHeight()) / 2
-(drawableWidth - binding.iv.getMeasuredWidth()) / 2,
-(drawableHeight - binding.iv.getMeasuredHeight()) / 2
)
iv.setImageMatrix(matrix)
iv.requestLayout()
binding.iv.setImageMatrix(matrix)
binding.iv.requestLayout()
}

animator.start()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ abstract class PageableMediaFragment : BasePagingFragment<Media>(), MediaDetailP
* ViewBinding
*/
private var _binding: FragmentSearchPaginatedBinding? = null
private val binding get() = _binding
private val binding get() = _binding!!

override val pagedListAdapter by lazy {
PagedMediaAdapter(categoryImagesCallback::onMediaClicked)
Expand All @@ -43,9 +43,9 @@ abstract class PageableMediaFragment : BasePagingFragment<Media>(), MediaDetailP
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
): View {
_binding = FragmentSearchPaginatedBinding.inflate(inflater, container, false)
return binding?.root
return binding.root
}

private val simpleDataObserver =
Expand All @@ -66,7 +66,7 @@ abstract class PageableMediaFragment : BasePagingFragment<Media>(), MediaDetailP
pagedListAdapter.currentList?.get(position)?.takeIf { it.filename != null }
.also {
pagedListAdapter.currentList?.loadAround(position)
binding?.paginatedSearchResultsList?.scrollToPosition(position)
binding.paginatedSearchResultsList.scrollToPosition(position)
}

override fun getTotalMediaCount(): Int = pagedListAdapter.itemCount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.R
import fr.free.nrw.commons.databinding.LayoutCategoryImagesBinding
import fr.free.nrw.commons.explore.paging.BaseViewHolder
import fr.free.nrw.commons.explore.paging.inflate
import kotlinx.android.synthetic.main.layout_category_images.*

class PagedMediaAdapter(private val onImageClicked: (Int) -> Unit) :
PagedListAdapter<Media, SearchImagesViewHolder>(object : DiffUtil.ItemCallback<Media>() {
Expand All @@ -32,17 +32,19 @@ class PagedMediaAdapter(private val onImageClicked: (Int) -> Unit) :

class SearchImagesViewHolder(containerView: View, val onImageClicked: (Int) -> Unit) :
BaseViewHolder<Pair<Media, Int>>(containerView) {
val binding = LayoutCategoryImagesBinding.bind(itemView)

override fun bind(item: Pair<Media, Int>) {
val media = item.first
categoryImageView.setOnClickListener { onImageClicked(item.second) }
categoryImageTitle.text = media.mostRelevantCaption
categoryImageView.setImageURI(media.thumbUrl)
binding.categoryImageView.setOnClickListener { onImageClicked(item.second) }
binding.categoryImageTitle.text = media.mostRelevantCaption
binding.categoryImageView.setImageURI(media.thumbUrl)
if (media.author?.isNotEmpty() == true) {
categoryImageAuthor.visibility = View.VISIBLE
categoryImageAuthor.text =
binding.categoryImageAuthor.visibility = View.VISIBLE
binding.categoryImageAuthor.text =
containerView.context.getString(R.string.image_uploaded_by, media.user)
} else {
categoryImageAuthor.visibility = View.GONE
binding.categoryImageAuthor.visibility = View.GONE
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import android.content.res.Configuration
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.*
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
Expand All @@ -14,11 +15,9 @@ import androidx.paging.PagedList
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.MergeAdapter
import fr.free.nrw.commons.R
import fr.free.nrw.commons.databinding.FragmentSearchPaginatedBinding
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
import fr.free.nrw.commons.utils.ViewUtil
import kotlinx.android.synthetic.main.fragment_search_paginated.*


abstract class BasePagingFragment<T> : CommonsDaggerSupportFragment(),
PagingContract.View<T> {
Expand All @@ -30,15 +29,21 @@ abstract class BasePagingFragment<T> : CommonsDaggerSupportFragment(),
private val mergeAdapter by lazy { MergeAdapter(pagedListAdapter, loadingAdapter) }
private var searchResults: LiveData<PagedList<T>>? = null

private var _binding: FragmentSearchPaginatedBinding? = null
private val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = inflater.inflate(R.layout.fragment_search_paginated, container, false)
): View {
_binding = FragmentSearchPaginatedBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
paginatedSearchResultsList.apply {
binding.paginatedSearchResultsList.apply {
layoutManager = GridLayoutManager(context, if (isPortrait) 1 else 2)
adapter = mergeAdapter
}
Expand All @@ -53,7 +58,7 @@ abstract class BasePagingFragment<T> : CommonsDaggerSupportFragment(),
*/
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
paginatedSearchResultsList.apply {
binding.paginatedSearchResultsList.apply {
layoutManager = GridLayoutManager(context, if (isPortrait) 1 else 2)
}
}
Expand All @@ -77,30 +82,30 @@ abstract class BasePagingFragment<T> : CommonsDaggerSupportFragment(),
}

override fun hideInitialLoadProgress() {
paginatedSearchInitialLoadProgress.visibility = GONE
binding.paginatedSearchInitialLoadProgress.visibility = GONE
}

override fun showInitialLoadInProgress() {
paginatedSearchInitialLoadProgress.visibility = VISIBLE
binding.paginatedSearchInitialLoadProgress.visibility = VISIBLE
}

override fun showSnackbar() {
ViewUtil.showShortSnackbar(paginatedSearchResultsList, errorTextId)
ViewUtil.showShortSnackbar(binding.paginatedSearchResultsList, errorTextId)
}

fun onQueryUpdated(query: String) {
injectedPresenter.onQueryUpdated(query)
}

override fun showEmptyText(query: String) {
contentNotFound.text = getEmptyText(query)
contentNotFound.visibility = VISIBLE
binding.contentNotFound.text = getEmptyText(query)
binding.contentNotFound.visibility = VISIBLE
}

abstract fun getEmptyText(query: String): String

override fun hideEmptyText() {
contentNotFound.visibility = GONE
binding.contentNotFound.visibility = GONE
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import fr.free.nrw.commons.R
import fr.free.nrw.commons.databinding.ListItemLoadMoreBinding
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.list_item_load_more.*

class FooterAdapter(private val onRefreshClicked: () -> Unit) :
ListAdapter<FooterItem, FooterViewHolder>(object :
Expand Down Expand Up @@ -45,8 +45,10 @@ open class FooterViewHolder(override val containerView: View) :
class LoadingViewHolder(containerView: View) : FooterViewHolder(containerView)
class RefreshViewHolder(containerView: View, onRefreshClicked: () -> Unit) :
FooterViewHolder(containerView) {
val binding = ListItemLoadMoreBinding.bind(itemView)

init {
listItemLoadMoreButton.setOnClickListener { onRefreshClicked() }
binding.listItemLoadMoreButton.setOnClickListener { onRefreshClicked() }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package fr.free.nrw.commons.upload

import android.os.Parcelable
import fr.free.nrw.commons.nearby.Place
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize

/**
* Holds a description of an item being uploaded by [UploadActivity]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.free.nrw.commons.upload
import android.os.Parcelable
import fr.free.nrw.commons.location.LatLng
import fr.free.nrw.commons.nearby.Place
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize

@Parcelize
data class WikidataPlace(
Expand Down
Loading