Migrate to ViewBindings (#1072) - WIP

This commit is contained in:
Benoit Marty 2020-12-16 02:49:22 +01:00
parent d02da1b97e
commit c1222737d6
6 changed files with 67 additions and 76 deletions

View File

@ -25,7 +25,7 @@ import android.widget.FrameLayout
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import im.vector.app.R
import im.vector.app.databinding.ViewButtonStateBinding
class ButtonStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
: FrameLayout(context, attrs, defStyle) {
@ -47,11 +47,15 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
// Big or Flat button
var button: Button
private val views: ViewButtonStateBinding
init {
View.inflate(context, R.layout.view_button_state, this)
inflate(context, R.layout.view_button_state, this)
views = ViewButtonStateBinding.bind(this)
layoutParams = LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
buttonStateRetry.setOnClickListener {
views.buttonStateRetry.setOnClickListener {
callback?.onRetryClicked()
}
@ -63,15 +67,15 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
.apply {
try {
if (getBoolean(R.styleable.ButtonStateView_bsv_use_flat_button, true)) {
button = buttonStateButtonFlat
buttonStateButtonBig.isVisible = false
button = views.buttonStateButtonFlat
views.buttonStateButtonBig.isVisible = false
} else {
button = buttonStateButtonBig
buttonStateButtonFlat.isVisible = false
button = views.buttonStateButtonBig
views.buttonStateButtonFlat.isVisible = false
}
button.text = getString(R.styleable.ButtonStateView_bsv_button_text)
buttonStateLoaded.setImageDrawable(getDrawable(R.styleable.ButtonStateView_bsv_loaded_image_src))
views.buttonStateLoaded.setImageDrawable(getDrawable(R.styleable.ButtonStateView_bsv_loaded_image_src))
} finally {
recycle()
}
@ -90,8 +94,8 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
button.isInvisible = true
}
buttonStateLoading.isVisible = newState == State.Loading
buttonStateLoaded.isVisible = newState == State.Loaded
buttonStateRetry.isVisible = newState == State.Error
views.buttonStateLoading.isVisible = newState == State.Loading
views.buttonStateLoaded.isVisible = newState == State.Loaded
views.buttonStateRetry.isVisible = newState == State.Error
}
}

View File

@ -24,7 +24,7 @@ import android.widget.FrameLayout
import androidx.core.view.isVisible
import im.vector.app.R
import im.vector.app.core.extensions.updateConstraintSet
import im.vector.app.databinding.ViewStateBinding
class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
: FrameLayout(context, attrs, defStyle) {
@ -42,6 +42,8 @@ class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
data class Error(val message: CharSequence? = null) : State()
}
private val views: ViewStateBinding
var eventCallback: EventCallback? = null
var contentView: View? = null
@ -58,33 +60,34 @@ class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
}
init {
View.inflate(context, R.layout.view_state, this)
inflate(context, R.layout.view_state, this)
views = ViewStateBinding.bind(this)
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
errorRetryView.setOnClickListener {
views.errorRetryView.setOnClickListener {
eventCallback?.onRetryClicked()
}
state = State.Content
}
private fun update(newState: State) {
progressBar.isVisible = newState is State.Loading
errorView.isVisible = newState is State.Error
emptyView.isVisible = newState is State.Empty
views.progressBar.isVisible = newState is State.Loading
views.errorView.isVisible = newState is State.Error
views.emptyView.isVisible = newState is State.Empty
contentView?.isVisible = newState is State.Content
when (newState) {
is State.Content -> Unit
is State.Loading -> Unit
is State.Empty -> {
emptyImageView.setImageDrawable(newState.image)
emptyView.updateConstraintSet {
views.emptyImageView.setImageDrawable(newState.image)
views.emptyView.updateConstraintSet {
it.constrainPercentHeight(R.id.emptyImageView, if (newState.isBigImage) 0.5f else 0.1f)
}
emptyMessageView.text = newState.message
emptyTitleView.text = newState.title
views.emptyMessageView.text = newState.message
views.emptyTitleView.text = newState.title
}
is State.Error -> {
errorMessageView.text = newState.message
views.errorMessageView.text = newState.message
}
}
}

View File

@ -38,7 +38,7 @@ class CallControlsView @JvmOverloads constructor(
var interactionListener: InteractionListener? = null
init {
View.inflate(context, R.layout.view_call_controls, this)
inflate(context, R.layout.view_call_controls, this)
// layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
views = ViewCallControlsBinding.bind(this)

View File

@ -26,6 +26,7 @@ import androidx.core.view.updateLayoutParams
import im.vector.app.R
import im.vector.app.core.di.HasScreenInjector
import im.vector.app.core.platform.ButtonStateView
import im.vector.app.databinding.VectorInviteViewBinding
import im.vector.app.features.home.AvatarRenderer
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
@ -46,12 +47,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
SMALL
}
private val inviteAvatarView: ImageView
private val inviteLabelView: TextView
private val inviteNameView: TextView
private val inviteIdentifierView: TextView
private val inviteAcceptView: ButtonStateView
private val inviteRejectView: ButtonStateView
private val views: VectorInviteViewBinding
@Inject lateinit var avatarRenderer: AvatarRenderer
var callback: Callback? = null
@ -60,9 +56,9 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
if (context is HasScreenInjector) {
context.injector().inject(this)
}
View.inflate(context, R.layout.vector_invite_view, this)
inviteAcceptView = findViewById(R.id.inviteAcceptView)
inviteAcceptView.callback = object : ButtonStateView.Callback {
inflate(context, R.layout.vector_invite_view, this)
views = VectorInviteViewBinding.bind(this)
views.inviteAcceptView.callback = object : ButtonStateView.Callback {
override fun onButtonClicked() {
callback?.onAcceptInvite()
}
@ -72,8 +68,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
}
}
inviteRejectView = findViewById(R.id.inviteRejectView)
inviteRejectView.callback = object : ButtonStateView.Callback {
views.inviteRejectView.callback = object : ButtonStateView.Callback {
override fun onButtonClicked() {
callback?.onRejectInvite()
}
@ -82,27 +77,22 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
callback?.onRejectInvite()
}
}
inviteAvatarView = findViewById(R.id.inviteAvatarView)
inviteLabelView = findViewById(R.id.inviteLabelView)
inviteNameView = findViewById(R.id.inviteNameView)
inviteIdentifierView = findViewById(R.id.inviteIdentifierView)
}
fun render(sender: RoomMemberSummary, mode: Mode = Mode.LARGE, changeMembershipState: ChangeMembershipState) {
if (mode == Mode.LARGE) {
updateLayoutParams { height = LayoutParams.MATCH_CONSTRAINT }
avatarRenderer.render(sender.toMatrixItem(), inviteAvatarView)
inviteIdentifierView.text = sender.userId
inviteNameView.text = sender.displayName
inviteLabelView.text = context.getString(R.string.send_you_invite)
avatarRenderer.render(sender.toMatrixItem(), views.inviteAvatarView)
views.inviteIdentifierView.text = sender.userId
views.inviteNameView.text = sender.displayName
views.inviteLabelView.text = context.getString(R.string.send_you_invite)
} else {
updateLayoutParams { height = LayoutParams.WRAP_CONTENT }
inviteAvatarView.visibility = View.GONE
inviteIdentifierView.visibility = View.GONE
inviteNameView.visibility = View.GONE
inviteLabelView.text = context.getString(R.string.invited_by, sender.userId)
views.inviteAvatarView.visibility = View.GONE
views.inviteIdentifierView.visibility = View.GONE
views.inviteNameView.visibility = View.GONE
views.inviteLabelView.text = context.getString(R.string.invited_by, sender.userId)
}
InviteButtonStateBinder.bind(inviteAcceptView, inviteRejectView, changeMembershipState)
InviteButtonStateBinder.bind(views.inviteAcceptView, views.inviteRejectView, changeMembershipState)
}
}

View File

@ -26,6 +26,7 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Group
import im.vector.app.R
import im.vector.app.databinding.MergeImageAttachmentOverlayBinding
import im.vector.lib.attachmentviewer.AttachmentEventListener
import im.vector.lib.attachmentviewer.AttachmentEvents
@ -38,38 +39,27 @@ class AttachmentOverlayView @JvmOverloads constructor(
var onPlayPause: ((play: Boolean) -> Unit)? = null
var videoSeekTo: ((progress: Int) -> Unit)? = null
private val counterTextView: TextView
private val infoTextView: TextView
private val shareImage: ImageView
private val overlayPlayPauseButton: ImageView
private val overlaySeekBar: SeekBar
private val views: MergeImageAttachmentOverlayBinding
var isPlaying = false
val videoControlsGroup: Group
var suspendSeekBarUpdate = false
init {
View.inflate(context, R.layout.merge_image_attachment_overlay, this)
inflate(context, R.layout.merge_image_attachment_overlay, this)
views = MergeImageAttachmentOverlayBinding.bind(this)
setBackgroundColor(Color.TRANSPARENT)
counterTextView = findViewById(R.id.overlayCounterText)
infoTextView = findViewById(R.id.overlayInfoText)
shareImage = findViewById(R.id.overlayShareButton)
videoControlsGroup = findViewById(R.id.overlayVideoControlsGroup)
overlayPlayPauseButton = findViewById(R.id.overlayPlayPauseButton)
overlaySeekBar = findViewById(R.id.overlaySeekBar)
findViewById<ImageView>(R.id.overlayBackButton).setOnClickListener {
views.overlayBackButton.setOnClickListener {
onBack?.invoke()
}
findViewById<ImageView>(R.id.overlayShareButton).setOnClickListener {
views.overlayShareButton.setOnClickListener {
onShareCallback?.invoke()
}
findViewById<ImageView>(R.id.overlayPlayPauseButton).setOnClickListener {
views.overlayPlayPauseButton.setOnClickListener {
onPlayPause?.invoke(!isPlaying)
}
overlaySeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
views.overlaySeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) {
videoSeekTo?.invoke(progress)
@ -87,19 +77,19 @@ class AttachmentOverlayView @JvmOverloads constructor(
}
fun updateWith(counter: String, senderInfo: String) {
counterTextView.text = counter
infoTextView.text = senderInfo
views.overlayCounterText.text = counter
views.overlayInfoText.text = senderInfo
}
override fun onEvent(event: AttachmentEvents) {
when (event) {
is AttachmentEvents.VideoEvent -> {
overlayPlayPauseButton.setImageResource(if (!event.isPlaying) R.drawable.ic_play_arrow else R.drawable.ic_pause)
views.overlayPlayPauseButton.setImageResource(if (!event.isPlaying) R.drawable.ic_play_arrow else R.drawable.ic_pause)
if (!suspendSeekBarUpdate) {
val safeDuration = (if (event.duration == 0) 100 else event.duration).toFloat()
val percent = ((event.progress / safeDuration) * 100f).toInt().coerceAtMost(100)
isPlaying = event.isPlaying
overlaySeekBar.progress = percent
views.overlaySeekBar.progress = percent
}
}
}

View File

@ -23,26 +23,30 @@ import android.widget.FrameLayout
import androidx.core.view.isVisible
import im.vector.app.R
import im.vector.app.core.utils.isAirplaneModeOn
import im.vector.app.databinding.ViewSyncStateBinding
import org.matrix.android.sdk.api.session.sync.SyncState
class SyncStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
: FrameLayout(context, attrs, defStyle) {
private val views: ViewSyncStateBinding
init {
View.inflate(context, R.layout.view_sync_state, this)
inflate(context, R.layout.view_sync_state, this)
views = ViewSyncStateBinding.bind(this)
}
fun render(newState: SyncState) {
syncStateProgressBar.isVisible = newState is SyncState.Running && newState.afterPause
views.syncStateProgressBar.isVisible = newState is SyncState.Running && newState.afterPause
if (newState == SyncState.NoNetwork) {
val isAirplaneModeOn = isAirplaneModeOn(context)
syncStateNoNetwork.isVisible = isAirplaneModeOn.not()
syncStateNoNetworkAirplane.isVisible = isAirplaneModeOn
views.syncStateNoNetwork.isVisible = isAirplaneModeOn.not()
views.syncStateNoNetworkAirplane.isVisible = isAirplaneModeOn
} else {
syncStateNoNetwork.isVisible = false
syncStateNoNetworkAirplane.isVisible = false
views.syncStateNoNetwork.isVisible = false
views.syncStateNoNetworkAirplane.isVisible = false
}
}
}