improved activity list performance

This commit is contained in:
Mariotaku Lee 2017-04-28 22:34:47 +08:00
parent 6bf9b30539
commit 6dfc4897de
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
1 changed files with 55 additions and 33 deletions

View File

@ -21,6 +21,8 @@ package org.mariotaku.twidere.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.database.Cursor
import android.database.CursorIndexOutOfBoundsException
import android.support.v4.util.LongSparseArray
import android.support.v4.widget.Space
import android.support.v7.widget.RecyclerView
@ -159,19 +161,17 @@ class ParcelableActivitiesAdapter(
val countIndex = itemCounts.getItemCountIndex(position)
when (countIndex) {
ITEM_INDEX_ACTIVITY -> {
val dataPosition = position - activityStartIndex
if (data is ObjectCursor) {
val cursor = (data as ObjectCursor).cursor
if (!cursor.moveToPosition(dataPosition)) return -1
val indices = (data as ObjectCursor).indices
return getFieldValue(position, readCursorValueAction = { cursor, indices ->
val accountKey = UserKey.valueOf(cursor.getString(indices[Activities.ACCOUNT_KEY]))
val timestamp = cursor.getLong(indices[Activities.TIMESTAMP])
val maxPosition = cursor.getLong(indices[Activities.MAX_SORT_POSITION])
val minPosition = cursor.getLong(indices[Activities.MIN_SORT_POSITION])
return ParcelableActivity.calculateHashCode(accountKey, timestamp, maxPosition,
minPosition).toLong()
}
return (countIndex.toLong() shl 32) or getActivity(position, false).hashCode().toLong()
ParcelableActivity.calculateHashCode(accountKey, timestamp, maxPosition,
minPosition)
}, readStatusValueAction = { activity ->
ParcelableActivity.calculateHashCode(activity.account_key, activity.timestamp,
activity.max_sort_position, activity.min_sort_position)
}, defValue = -1, raw = false).toLong()
}
else -> {
return (countIndex.toLong() shl 32) or getItemViewType(position).toLong()
@ -179,18 +179,6 @@ class ParcelableActivitiesAdapter(
}
}
fun getTimestamp(adapterPosition: Int, raw: Boolean = false): Long {
val dataPosition = adapterPosition - activityStartIndex
if (dataPosition < 0 || dataPosition >= getActivityCount(raw)) return RecyclerView.NO_ID
if (data is ObjectCursor) {
val cursor = (data as ObjectCursor).cursor
if (!cursor.safeMoveToPosition(dataPosition)) return -1
val indices = (data as ObjectCursor).indices
return cursor.safeGetLong(indices[Activities.TIMESTAMP])
}
return getActivity(adapterPosition, raw).timestamp
}
override fun getActivity(position: Int, raw: Boolean): ParcelableActivity {
return getActivityInternal(position, raw, false)
}
@ -200,10 +188,6 @@ class ParcelableActivitiesAdapter(
return data!!.size
}
fun getData(): List<ParcelableActivity>? {
return data
}
override fun setData(data: List<ParcelableActivity>?) {
if (data is CursorActivitiesFragment.CursorActivitiesLoader.ActivityCursor) {
filteredUserKeys = data.filteredUserIds
@ -277,8 +261,8 @@ class ParcelableActivitiesAdapter(
if (isGapItem(position)) {
return ITEM_VIEW_TYPE_GAP
}
val activity = getActivityInternal(position, raw = false, reuse = true)
when (activity.action) {
val action = getAction(position)
when (action) {
Activity.Action.MENTION, Activity.Action.QUOTE, Activity.Action.REPLY -> {
return ITEM_VIEW_TYPE_STATUS
}
@ -290,12 +274,12 @@ class ParcelableActivitiesAdapter(
Activity.Action.FAVORITED_MEDIA_TAGGED, Activity.Action.JOINED_TWITTER -> {
if (mentionsOnly) return ITEM_VIEW_TYPE_EMPTY
filteredUserKeys?.let {
// ParcelableActivityUtils.initAfterFilteredSourceIds(activity, it, followingOnly)
// filterIdCache[activity._id] = activity.after_filtered_source_ids
val sourceIds = activity.after_filtered_source_keys
if (sourceIds != null && sourceIds.isEmpty()) {
return ITEM_VIEW_TYPE_EMPTY
}
// ParcelableActivityUtils.initAfterFilteredSourceIds(activity, it, followingOnly)
// filterIdCache[activity._id] = activity.after_filtered_source_ids
// val sourceIds = activity.after_filtered_source_keys
// if (sourceIds != null && sourceIds.isEmpty()) {
// return ITEM_VIEW_TYPE_EMPTY
// }
}
return ITEM_VIEW_TYPE_TITLE_SUMMARY
}
@ -339,6 +323,26 @@ class ParcelableActivitiesAdapter(
return range.indexOfFirst { timestamp >= getTimestamp(it, raw) }
}
fun getTimestamp(adapterPosition: Int, raw: Boolean = false): Long {
return getFieldValue(adapterPosition, readCursorValueAction = { cursor, indices ->
cursor.safeGetLong(indices[Activities.TIMESTAMP])
}, readStatusValueAction = { activity ->
activity.timestamp
}, defValue = -1, raw = raw)
}
fun getAction(adapterPosition: Int, raw: Boolean = false): String? {
return getFieldValue(adapterPosition, readCursorValueAction = { cursor, indices ->
cursor.getString(indices[Activities.ACTION])
}, readStatusValueAction = { activity ->
activity.action
}, defValue = null, raw = raw)
}
fun getData(): List<ParcelableActivity>? {
return data
}
private fun updateItemCount() {
itemCounts[0] = getActivityCount(false)
itemCounts[1] = if (ILoadMoreSupportAdapter.END in loadMoreIndicatorPosition) 1 else 0
@ -363,6 +367,24 @@ class ParcelableActivitiesAdapter(
}
}
private inline fun <T> getFieldValue(position: Int,
readCursorValueAction: (cursor: Cursor, indices: ObjectCursor.CursorIndices<ParcelableActivity>) -> T,
readStatusValueAction: (status: ParcelableActivity) -> T,
defValue: T, raw: Boolean = false): T {
if (data is ObjectCursor) {
val dataPosition = position - activityStartIndex
if (dataPosition < 0 || dataPosition >= getActivityCount(true)) {
throw CursorIndexOutOfBoundsException("index: $position, valid range is $0..${getActivityCount(true)}")
}
val cursor = (data as ObjectCursor).cursor
if (!cursor.safeMoveToPosition(dataPosition)) return defValue
val indices = (data as ObjectCursor).indices
return readCursorValueAction(cursor, indices)
}
return readStatusValueAction(getActivityInternal(position, raw, false))
}
interface ActivityAdapterListener {
fun onGapClick(holder: GapViewHolder, position: Int)