migrating to ViewBinding part 6: the final cleanup (#2117)

This commit is contained in:
Konrad Pozniak 2021-03-21 12:42:28 +01:00 committed by GitHub
parent bea5098cc1
commit f293670c14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 52 additions and 62 deletions

View file

@ -1,7 +1,7 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-parcelize'
apply from: "../instance-build.gradle" apply from: "../instance-build.gradle"
@ -64,9 +64,6 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
androidExtensions {
experimental = true
}
buildFeatures { buildFeatures {
viewBinding true viewBinding true
} }

View file

@ -76,10 +76,10 @@ import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.mikepenz.iconics.utils.colorInt import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp import com.mikepenz.iconics.utils.sizeDp
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.util.* import java.util.Locale
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min

View file

@ -21,6 +21,7 @@ import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.keylesspalace.tusky.R import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.report.model.StatusViewState import com.keylesspalace.tusky.components.report.model.StatusViewState
import com.keylesspalace.tusky.databinding.ItemReportStatusBinding
import com.keylesspalace.tusky.entity.Emoji import com.keylesspalace.tusky.entity.Emoji
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.interfaces.LinkListener import com.keylesspalace.tusky.interfaces.LinkListener
@ -28,16 +29,15 @@ import com.keylesspalace.tusky.util.*
import com.keylesspalace.tusky.util.StatusViewHelper.Companion.COLLAPSE_INPUT_FILTER import com.keylesspalace.tusky.util.StatusViewHelper.Companion.COLLAPSE_INPUT_FILTER
import com.keylesspalace.tusky.util.StatusViewHelper.Companion.NO_INPUT_FILTER import com.keylesspalace.tusky.util.StatusViewHelper.Companion.NO_INPUT_FILTER
import com.keylesspalace.tusky.viewdata.toViewData import com.keylesspalace.tusky.viewdata.toViewData
import kotlinx.android.synthetic.main.item_report_status.view.*
import java.util.* import java.util.*
class StatusViewHolder( class StatusViewHolder(
itemView: View, private val binding: ItemReportStatusBinding,
private val statusDisplayOptions: StatusDisplayOptions, private val statusDisplayOptions: StatusDisplayOptions,
private val viewState: StatusViewState, private val viewState: StatusViewState,
private val adapterHandler: AdapterHandler, private val adapterHandler: AdapterHandler,
private val getStatusForPosition: (Int) -> Status? private val getStatusForPosition: (Int) -> Status?
) : RecyclerView.ViewHolder(itemView) { ) : RecyclerView.ViewHolder(binding.root) {
private val mediaViewHeight = itemView.context.resources.getDimensionPixelSize(R.dimen.status_media_preview_height) private val mediaViewHeight = itemView.context.resources.getDimensionPixelSize(R.dimen.status_media_preview_height)
private val statusViewHelper = StatusViewHelper(itemView) private val statusViewHelper = StatusViewHelper(itemView)
@ -56,16 +56,16 @@ class StatusViewHolder(
} }
init { init {
itemView.statusSelection.setOnCheckedChangeListener { _, isChecked -> binding.statusSelection.setOnCheckedChangeListener { _, isChecked ->
status()?.let { status -> status()?.let { status ->
adapterHandler.setStatusChecked(status, isChecked) adapterHandler.setStatusChecked(status, isChecked)
} }
} }
itemView.status_media_preview_container.clipToOutline = true binding.statusMediaPreviewContainer.clipToOutline = true
} }
fun bind(status: Status) { fun bind(status: Status) {
itemView.statusSelection.isChecked = adapterHandler.isStatusChecked(status.id) binding.statusSelection.isChecked = adapterHandler.isStatusChecked(status.id)
updateTextView() updateTextView()
@ -86,18 +86,18 @@ class StatusViewHolder(
if (status.spoilerText.isBlank()) { if (status.spoilerText.isBlank()) {
setTextVisible(true, status.content, status.mentions, status.emojis, adapterHandler) setTextVisible(true, status.content, status.mentions, status.emojis, adapterHandler)
itemView.statusContentWarningButton.hide() binding.statusContentWarningButton.hide()
itemView.statusContentWarningDescription.hide() binding.statusContentWarningDescription.hide()
} else { } else {
val emojiSpoiler = status.spoilerText.emojify(status.emojis, itemView.statusContentWarningDescription, statusDisplayOptions.animateEmojis) val emojiSpoiler = status.spoilerText.emojify(status.emojis, binding.statusContentWarningDescription, statusDisplayOptions.animateEmojis)
itemView.statusContentWarningDescription.text = emojiSpoiler binding.statusContentWarningDescription.text = emojiSpoiler
itemView.statusContentWarningDescription.show() binding.statusContentWarningDescription.show()
itemView.statusContentWarningButton.show() binding.statusContentWarningButton.show()
setContentWarningButtonText(viewState.isContentShow(status.id, true)) setContentWarningButtonText(viewState.isContentShow(status.id, true))
itemView.statusContentWarningButton.setOnClickListener { binding.statusContentWarningButton.setOnClickListener {
status()?.let { status -> status()?.let { status ->
val contentShown = viewState.isContentShow(status.id, true) val contentShown = viewState.isContentShow(status.id, true)
itemView.statusContentWarningDescription.invalidate() binding.statusContentWarningDescription.invalidate()
viewState.setContentShow(status.id, !contentShown) viewState.setContentShow(status.id, !contentShown)
setTextVisible(!contentShown, status.content, status.mentions, status.emojis, adapterHandler) setTextVisible(!contentShown, status.content, status.mentions, status.emojis, adapterHandler)
setContentWarningButtonText(!contentShown) setContentWarningButtonText(!contentShown)
@ -110,9 +110,9 @@ class StatusViewHolder(
private fun setContentWarningButtonText(contentShown: Boolean) { private fun setContentWarningButtonText(contentShown: Boolean) {
if(contentShown) { if(contentShown) {
itemView.statusContentWarningButton.setText(R.string.status_content_warning_show_less) binding.statusContentWarningButton.setText(R.string.status_content_warning_show_less)
} else { } else {
itemView.statusContentWarningButton.setText(R.string.status_content_warning_show_more) binding.statusContentWarningButton.setText(R.string.status_content_warning_show_more)
} }
} }
@ -122,26 +122,26 @@ class StatusViewHolder(
emojis: List<Emoji>, emojis: List<Emoji>,
listener: LinkListener) { listener: LinkListener) {
if (expanded) { if (expanded) {
val emojifiedText = content.emojify(emojis, itemView.statusContent, statusDisplayOptions.animateEmojis) val emojifiedText = content.emojify(emojis, binding.statusContent, statusDisplayOptions.animateEmojis)
LinkHelper.setClickableText(itemView.statusContent, emojifiedText, mentions, listener) LinkHelper.setClickableText(binding.statusContent, emojifiedText, mentions, listener)
} else { } else {
LinkHelper.setClickableMentions(itemView.statusContent, mentions, listener) LinkHelper.setClickableMentions(binding.statusContent, mentions, listener)
} }
if (itemView.statusContent.text.isNullOrBlank()) { if (binding.statusContent.text.isNullOrBlank()) {
itemView.statusContent.hide() binding.statusContent.hide()
} else { } else {
itemView.statusContent.show() binding.statusContent.show()
} }
} }
private fun setCreatedAt(createdAt: Date?) { private fun setCreatedAt(createdAt: Date?) {
if (statusDisplayOptions.useAbsoluteTime) { if (statusDisplayOptions.useAbsoluteTime) {
itemView.timestampInfo.text = statusViewHelper.getAbsoluteTime(createdAt) binding.timestampInfo.text = statusViewHelper.getAbsoluteTime(createdAt)
} else { } else {
itemView.timestampInfo.text = if (createdAt != null) { binding.timestampInfo.text = if (createdAt != null) {
val then = createdAt.time val then = createdAt.time
val now = System.currentTimeMillis() val now = System.currentTimeMillis()
TimestampUtils.getRelativeTimeSpanString(itemView.timestampInfo.context, then, now) TimestampUtils.getRelativeTimeSpanString(binding.timestampInfo.context, then, now)
} else { } else {
// unknown minutes~ // unknown minutes~
"?m" "?m"
@ -149,28 +149,27 @@ class StatusViewHolder(
} }
} }
private fun setupCollapsedState(collapsible: Boolean, collapsed: Boolean, expanded: Boolean, spoilerText: String) { private fun setupCollapsedState(collapsible: Boolean, collapsed: Boolean, expanded: Boolean, spoilerText: String) {
/* input filter for TextViews have to be set before text */ /* input filter for TextViews have to be set before text */
if (collapsible && (expanded || TextUtils.isEmpty(spoilerText))) { if (collapsible && (expanded || TextUtils.isEmpty(spoilerText))) {
itemView.buttonToggleContent.setOnClickListener{ binding.buttonToggleContent.setOnClickListener{
status()?.let { status -> status()?.let { status ->
viewState.setCollapsed(status.id, !collapsed) viewState.setCollapsed(status.id, !collapsed)
updateTextView() updateTextView()
} }
} }
itemView.buttonToggleContent.show() binding.buttonToggleContent.show()
if (collapsed) { if (collapsed) {
itemView.buttonToggleContent.setText(R.string.status_content_show_more) binding.buttonToggleContent.setText(R.string.status_content_show_more)
itemView.statusContent.filters = COLLAPSE_INPUT_FILTER binding.statusContent.filters = COLLAPSE_INPUT_FILTER
} else { } else {
itemView.buttonToggleContent.setText(R.string.status_content_show_less) binding.buttonToggleContent.setText(R.string.status_content_show_less)
itemView.statusContent.filters = NO_INPUT_FILTER binding.statusContent.filters = NO_INPUT_FILTER
} }
} else { } else {
itemView.buttonToggleContent.hide() binding.buttonToggleContent.hide()
itemView.statusContent.filters = NO_INPUT_FILTER binding.statusContent.filters = NO_INPUT_FILTER
} }
} }

View file

@ -20,8 +20,8 @@ import android.view.ViewGroup
import androidx.paging.PagedListAdapter import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.report.model.StatusViewState import com.keylesspalace.tusky.components.report.model.StatusViewState
import com.keylesspalace.tusky.databinding.ItemReportStatusBinding
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.util.StatusDisplayOptions import com.keylesspalace.tusky.util.StatusDisplayOptions
@ -29,29 +29,25 @@ class StatusesAdapter(
private val statusDisplayOptions: StatusDisplayOptions, private val statusDisplayOptions: StatusDisplayOptions,
private val statusViewState: StatusViewState, private val statusViewState: StatusViewState,
private val adapterHandler: AdapterHandler private val adapterHandler: AdapterHandler
) : PagedListAdapter<Status, RecyclerView.ViewHolder>(STATUS_COMPARATOR) { ) : PagedListAdapter<Status, StatusViewHolder>(STATUS_COMPARATOR) {
private val statusForPosition: (Int) -> Status? = { position: Int -> private val statusForPosition: (Int) -> Status? = { position: Int ->
if (position != RecyclerView.NO_POSITION) getItem(position) else null if (position != RecyclerView.NO_POSITION) getItem(position) else null
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StatusViewHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val binding = ItemReportStatusBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val view = LayoutInflater.from(parent.context) return StatusViewHolder(binding, statusDisplayOptions, statusViewState, adapterHandler,
.inflate(R.layout.item_report_status, parent, false)
return StatusViewHolder(view, statusDisplayOptions, statusViewState, adapterHandler,
statusForPosition) statusForPosition)
} }
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: StatusViewHolder, position: Int) {
getItem(position)?.let { status -> getItem(position)?.let { status ->
(holder as? StatusViewHolder)?.bind(status) holder.bind(status)
} }
} }
companion object { companion object {
val STATUS_COMPARATOR = object : DiffUtil.ItemCallback<Status>() { val STATUS_COMPARATOR = object : DiffUtil.ItemCallback<Status>() {
override fun areContentsTheSame(oldItem: Status, newItem: Status): Boolean = override fun areContentsTheSame(oldItem: Status, newItem: Status): Boolean =
oldItem == newItem oldItem == newItem
@ -59,7 +55,5 @@ class StatusesAdapter(
override fun areItemsTheSame(oldItem: Status, newItem: Status): Boolean = override fun areItemsTheSame(oldItem: Status, newItem: Status): Boolean =
oldItem.id == newItem.id oldItem.id == newItem.id
} }
} }
} }

View file

@ -23,7 +23,7 @@ import androidx.room.PrimaryKey
import androidx.room.TypeConverters import androidx.room.TypeConverters
import com.keylesspalace.tusky.entity.NewPoll import com.keylesspalace.tusky.entity.NewPoll
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Entity @Entity
@TypeConverters(Converters::class) @TypeConverters(Converters::class)

View file

@ -22,7 +22,7 @@ import com.google.gson.JsonElement
import com.google.gson.JsonParseException import com.google.gson.JsonParseException
import com.google.gson.annotations.JsonAdapter import com.google.gson.annotations.JsonAdapter
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class Attachment( data class Attachment(

View file

@ -17,7 +17,7 @@ package com.keylesspalace.tusky.entity
import android.os.Parcelable import android.os.Parcelable
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class Emoji( data class Emoji(

View file

@ -17,7 +17,7 @@ package com.keylesspalace.tusky.entity
import android.os.Parcelable import android.os.Parcelable
import com.google.gson.annotations.SerializedName import com.google.gson.annotations.SerializedName
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
data class NewStatus( data class NewStatus(
val status: String, val status: String,

View file

@ -28,7 +28,7 @@ import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.SaveTootHelper import com.keylesspalace.tusky.util.SaveTootHelper
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response

View file

@ -3,7 +3,7 @@ package com.keylesspalace.tusky.viewdata
import android.os.Parcelable import android.os.Parcelable
import com.keylesspalace.tusky.entity.Attachment import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class AttachmentViewData( data class AttachmentViewData(

View file

@ -1,11 +1,11 @@
buildscript { buildscript {
ext.kotlin_version = '1.4.21' ext.kotlin_version = '1.4.31'
repositories { repositories {
google() google()
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.1.1' classpath 'com.android.tools.build:gradle:4.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }