diff --git a/changelog.d/3990.bugfix b/changelog.d/3990.bugfix new file mode 100644 index 0000000000..19bf9c65d1 --- /dev/null +++ b/changelog.d/3990.bugfix @@ -0,0 +1 @@ +- Fix memory leak on RoomDetailFragment (ValueAnimator) \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/core/ui/views/JoinConferenceView.kt b/vector/src/main/java/im/vector/app/core/ui/views/JoinConferenceView.kt new file mode 100644 index 0000000000..fa1e2c1403 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/ui/views/JoinConferenceView.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.ui.views + +import android.animation.Animator +import android.animation.ArgbEvaluator +import android.animation.ValueAnimator +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.core.content.ContextCompat +import im.vector.app.R +import im.vector.app.databinding.ViewJoinConferenceBinding + +class JoinConferenceView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : FrameLayout(context, attrs, defStyleAttr) { + + var views: ViewJoinConferenceBinding? = null + var onJoinClicked: (() -> Unit)? = null + var backgroundAnimator: Animator? = null + + init { + inflate(context, R.layout.view_join_conference, this) + } + + @SuppressLint("Recycle") + override fun onAttachedToWindow() { + super.onAttachedToWindow() + views = ViewJoinConferenceBinding.bind(this) + views?.joinConferenceButton?.setOnClickListener { onJoinClicked?.invoke() } + val colorFrom = ContextCompat.getColor(context, R.color.palette_element_green) + val colorTo = ContextCompat.getColor(context, R.color.join_conference_animated_color) + // Animate button color to highlight + backgroundAnimator = ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo).apply { + repeatMode = ValueAnimator.REVERSE + repeatCount = ValueAnimator.INFINITE + duration = 500 + addUpdateListener { animator -> + val color = animator.animatedValue as Int + views?.joinConferenceButton?.setBackgroundColor(color) + } + } + backgroundAnimator?.start() + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + views = null + backgroundAnimator?.cancel() + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 847b06fb45..d45aa69cf3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -16,7 +16,6 @@ package im.vector.app.features.home.room.detail -import android.animation.ArgbEvaluator import android.annotation.SuppressLint import android.app.Activity import android.content.Intent @@ -66,7 +65,6 @@ import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState -import com.google.android.material.button.MaterialButton import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.jakewharton.rxbinding3.view.focusChanges import com.jakewharton.rxbinding3.widget.textChanges @@ -93,6 +91,7 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.ui.views.CurrentCallsView import im.vector.app.core.ui.views.CurrentCallsViewPresenter import im.vector.app.core.ui.views.FailedMessagesWarningView +import im.vector.app.core.ui.views.JoinConferenceView import im.vector.app.core.ui.views.NotificationAreaView import im.vector.app.core.utils.Debouncer import im.vector.app.core.utils.DimensionConverter @@ -217,7 +216,6 @@ import java.net.URL import java.util.UUID import java.util.concurrent.TimeUnit import javax.inject.Inject -import android.animation.ValueAnimator @Parcelize data class RoomDetailArgs( @@ -869,20 +867,8 @@ class RoomDetailFragment @Inject constructor( } } val joinConfItem = menu.findItem(R.id.join_conference) - joinConfItem.actionView.findViewById(R.id.join_conference_button).also { joinButton -> - joinButton.setOnClickListener { roomDetailViewModel.handle(RoomDetailAction.JoinJitsiCall) } - val colorFrom = ContextCompat.getColor(joinButton.context, R.color.palette_element_green) - val colorTo = ContextCompat.getColor(joinButton.context, R.color.join_conference_animated_color) - // Animate button color to highlight - ValueAnimator.ofObject(ArgbEvaluator(), colorFrom, colorTo).apply { - repeatMode = ValueAnimator.REVERSE - repeatCount = ValueAnimator.INFINITE - duration = 500 - addUpdateListener { animator -> - val color = animator.animatedValue as Int - joinButton.setBackgroundColor(color) - } - }.start() + (joinConfItem.actionView as? JoinConferenceView)?.onJoinClicked = { + roomDetailViewModel.handle(RoomDetailAction.JoinJitsiCall) } } diff --git a/vector/src/main/res/layout/layout_join_conference_action.xml b/vector/src/main/res/layout/layout_join_conference_action.xml new file mode 100644 index 0000000000..4e2c792904 --- /dev/null +++ b/vector/src/main/res/layout/layout_join_conference_action.xml @@ -0,0 +1,6 @@ + + diff --git a/vector/src/main/res/layout/view_join_conference.xml b/vector/src/main/res/layout/view_join_conference.xml index 81e595c3de..c47eddc18f 100644 --- a/vector/src/main/res/layout/view_join_conference.xml +++ b/vector/src/main/res/layout/view_join_conference.xml @@ -1,19 +1,21 @@ - + android:paddingEnd="4dp">