Fix pool limits and y-translation issues with CFv2 recycler view.

This commit is contained in:
Cody Henthorne
2023-06-07 12:51:08 -04:00
committed by GitHub
parent d6a03df087
commit 7e0e6c2786
6 changed files with 101 additions and 6 deletions

View File

@@ -10,6 +10,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.core.text.HtmlCompat
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.RecyclerView
import com.google.android.exoplayer2.MediaItem
import org.signal.core.util.logging.Log
import org.signal.core.util.toOptional
@@ -74,7 +75,7 @@ class ConversationAdapterV2(
private val condensedMode: ConversationItemDisplayMode? = null
init {
registerFactory(ThreadHeader::class.java, ::ThreadHeaderViewHolder, R.layout.conversation_item_banner)
registerFactory(ThreadHeader::class.java, ::ThreadHeaderViewHolder, R.layout.conversation_item_thread_header)
registerFactory(ConversationUpdate::class.java) { parent ->
val view = CachedInflater.from(parent.context).inflate<View>(R.layout.conversation_item_update, parent, false)
@@ -102,6 +103,27 @@ class ConversationAdapterV2(
}
}
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
for ((model, type) in itemTypes) {
val count: Int = when (model) {
ThreadHeader::class.java -> 1
ConversationUpdate::class.java -> 5
OutgoingTextOnly::class.java -> 25
OutgoingMedia::class.java -> 15
IncomingTextOnly::class.java -> 25
IncomingMedia::class.java -> 15
Placeholder::class.java -> 5
else -> 0
}
if (count > 0) {
recyclerView.recycledViewPool.setMaxRecycledViews(type, count)
}
}
}
/** [messagePosition] is one-based index and adapter is zero-based. */
fun getAdapterPositionForMessagePosition(messagePosition: Int): Int {
return messagePosition - 1

View File

@@ -13,9 +13,11 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.Rect
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
@@ -38,6 +40,7 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.core.app.ActivityOptionsCompat
import androidx.core.content.ContextCompat
@@ -114,6 +117,7 @@ import org.thoughtcrime.securesms.contactshare.SharedContactDetailsActivity
import org.thoughtcrime.securesms.conversation.AttachmentKeyboardButton
import org.thoughtcrime.securesms.conversation.BadDecryptLearnMoreDialog
import org.thoughtcrime.securesms.conversation.ConversationAdapter
import org.thoughtcrime.securesms.conversation.ConversationHeaderView
import org.thoughtcrime.securesms.conversation.ConversationIntents
import org.thoughtcrime.securesms.conversation.ConversationIntents.ConversationScreenType
import org.thoughtcrime.securesms.conversation.ConversationItem
@@ -321,6 +325,7 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
private lateinit var attachmentManager: AttachmentManager
private lateinit var multiselectItemDecoration: MultiselectItemDecoration
private lateinit var openableGiftItemDecoration: OpenableGiftItemDecoration
private lateinit var threadHeaderMarginDecoration: ThreadHeaderMarginDecoration
private var animationsAllowed = false
private var actionMode: ActionMode? = null
@@ -394,6 +399,8 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
.addTo(disposables)
container.fragmentManager = childFragmentManager
ToolbarDependentMarginListener(binding.toolbar)
}
override fun onResume() {
@@ -422,6 +429,11 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
EventBus.getDefault().unregister(this)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
ToolbarDependentMarginListener(binding.toolbar)
}
override fun onDestroyView() {
super.onDestroyView()
if (pinnedShortcutReceiver != null) {
@@ -861,7 +873,6 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
adapter::getAdapterPositionForMessagePosition
)
ConversationAdapter.initializePool(binding.conversationItemRecycler.recycledViewPool)
adapter.setPagingController(viewModel.pagingController)
recyclerViewColorizer = RecyclerViewColorizer(binding.conversationItemRecycler)
@@ -895,6 +906,9 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
true
}
)
threadHeaderMarginDecoration = ThreadHeaderMarginDecoration()
binding.conversationItemRecycler.addItemDecoration(threadHeaderMarginDecoration)
}
private fun initializeGiphyMp4(): GiphyMp4ProjectionRecycler {
@@ -2654,4 +2668,30 @@ class ConversationFragment : LoggingFragment(R.layout.v2_conversation_fragment)
}
//endregion
private inner class ToolbarDependentMarginListener(private val toolbar: Toolbar) : ViewTreeObserver.OnGlobalLayoutListener {
init {
toolbar.viewTreeObserver.addOnGlobalLayoutListener(this)
}
override fun onGlobalLayout() {
val rect = Rect()
toolbar.getGlobalVisibleRect(rect)
threadHeaderMarginDecoration.toolbarMargin = rect.bottom + 16.dp
binding.conversationItemRecycler.invalidateItemDecorations()
toolbar.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
private inner class ThreadHeaderMarginDecoration : RecyclerView.ItemDecoration() {
var toolbarMargin: Int = 0
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
super.getItemOffsets(outRect, view, parent, state)
if (view is ConversationHeaderView) {
outRect.top = toolbarMargin
}
}
}
}