Merge pull request #3991 from vector-im/feature/fga/fix_memory_leak_room_detail

Fix memory leak on RoomDetailFragment
This commit is contained in:
Benoit Marty 2021-09-08 17:28:26 +02:00 committed by GitHub
commit fcd72fd9e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 24 deletions

1
changelog.d/3990.bugfix Normal file
View File

@ -0,0 +1 @@
- Fix memory leak on RoomDetailFragment (ValueAnimator)

View File

@ -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()
}
}

View File

@ -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<MaterialButton>(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)
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<im.vector.app.core.ui.views.JoinConferenceView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="4dp"
android:paddingEnd="4dp" />

View File

@ -1,19 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="4dp"
tools:parentTag="android.widget.FrameLayout"
android:paddingStart="4dp"
android:layout_width="wrap_content">
android:paddingEnd="4dp">
<Button
android:id="@+id/join_conference_button"
android:layout_width="56dp"
android:layout_height="wrap_content"
android:minHeight="32dp"
app:iconPadding="0dp"
app:iconGravity="textStart"
app:icon="@drawable/ic_call_video_small"
app:iconGravity="textStart"
app:iconPadding="0dp"
app:iconTint="@color/element_background_light" />
</FrameLayout>
</merge>

View File

@ -39,7 +39,7 @@
<item android:id="@+id/join_conference"
android:title="@string/join"
app:actionLayout="@layout/view_join_conference"
app:actionLayout="@layout/layout_join_conference_action"
app:showAsAction="always"
/>