From b36d3f56021986c59a2e6e6a27e432d4a944dedb Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Wed, 21 Aug 2019 09:18:37 +0300 Subject: [PATCH 1/3] ImagePreloadWatcher preload logic updated. --- .../com/omega_r/base/simple/MainActivity.kt | 53 +++++++-------- build.gradle | 4 +- .../omega_r/base/adapters/OmegaListAdapter.kt | 65 ++++++++++++++++--- 3 files changed, 86 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/omega_r/base/simple/MainActivity.kt b/app/src/main/java/com/omega_r/base/simple/MainActivity.kt index 68e885f..601baac 100644 --- a/app/src/main/java/com/omega_r/base/simple/MainActivity.kt +++ b/app/src/main/java/com/omega_r/base/simple/MainActivity.kt @@ -31,36 +31,37 @@ class MainActivity : OmegaActivity(), MainView { @InjectPresenter override lateinit var presenter: MainPresenter + private val images = listOf( + Image.from("https://images.wallpaperscraft.ru/image/gora_vershina_pik_146078_3840x2400.jpg"), + Image.from("https://hubblesite.org/uploads/image_file/image_attachment/31803/STSCI-H-p1935b-m-2000x1827.png"), + Image.from("https://hubblesite.org/uploads/image_file/image_attachment/31726/STSCI-H-p1918a-f-2000x2000.png"), + Image.from("https://images.wallpaperscraft.ru/image/basketbolnoe_koltso_shchitok_koltso_146103_3840x2160.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/kot_okno_vzgliad_146100_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/reka_obryv_skaly_146093_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/ozero_bereg_kamni_146091_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/gory_skaly_zasnezhennyj_146085_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/piatna_kraska_rzhavchina_146084_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/zdanie_arhitektura_minimalizm_146082_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/gora_vershina_pik_146078_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/setchatyj_struktura_relef_146075_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/zontiki_raznotsvetnyj_dekoratsiia_146072_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/tsvety_fioletovyj_buket_146070_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/okno_steklo_mokryj_146068_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/limon_dolki_pattern_146063_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/siluet_temnyj_zakat_146060_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/tsitata_chtenie_um_146059_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/devushka_siluet_solntse_146058_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/zdanie_arhitektura_sovremennyj_146056_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/mercedes_mashina_chernyj_146054_3840x2400.jpg"), + Image.from("https://images.wallpaperscraft.ru/image/kamen_skala_sneg_146052_3840x2400.jpg"), + Image.from("https://hubblesite.org/uploads/image_file/image_attachment/31803/STSCI-H-p1935b-m-2000x1827.png") + ) + private val adapter = OmegaAutoAdapter.create(R.layout.item_test_3, ::onClickItem) { bindImage(R.id.imageview) }.apply { watcher = OmegaListAdapter.ImagePreloadWatcher(this) - list = listOf( - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?156"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?256"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?35"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?45"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?56"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?64"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?79"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?85"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?91"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?102"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?113"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?124"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?135"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?146"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?1578"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?169"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?174"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?185"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?1956"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?201"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?212"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?2212"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?231"), - Image.from("https://i.pinimg.com/originals/d6/68/ab/d668abc72809303852c27275e6a56775.gif?242") - ) + list = images } private val recyclerView: RecyclerView by bind(R.id.recyclerview, adapter) { diff --git a/build.gradle b/build.gradle index 9508193..9efd19c 100644 --- a/build.gradle +++ b/build.gradle @@ -5,14 +5,14 @@ ext { }// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.3.31' + ext.kotlin_version = '1.3.41' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:3.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt b/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt index 11b9f60..da5f752 100644 --- a/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt +++ b/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt @@ -1,10 +1,14 @@ package com.omega_r.base.adapters +import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.omega_r.libs.omegatypes.Image +import kotlin.math.max +import kotlin.math.min /** * Created by Anton Knyazev on 04.04.2019. @@ -52,20 +56,65 @@ abstract class OmegaListAdapter : OmegaAdapter(), ListableAdapter } - class ImagePreloadWatcher(private val adapter: OmegaListAdapter) : Watcher { + class ImagePreloadWatcher( + private val adapter: OmegaListAdapter, + private val maxPreloadCount: Int = 4 + ) : Watcher { - private var lastPosition: Int = -1 + private var lastEnd: Int = 0 + private var lastStart: Int = 0 + private var lastFirstVisible = -1 override fun bindPosition(position: Int, recyclerView: RecyclerView) { - val childCount = recyclerView.childCount - val preloadPosition = if (lastPosition < position) { - position + childCount + val layoutManager = recyclerView.layoutManager as? LinearLayoutManager ?: return + val context = recyclerView.context + val firstVisible = layoutManager.findFirstVisibleItemPosition() + val lastVisible = layoutManager.findLastVisibleItemPosition() + val visibleCount = lastVisible - firstVisible + + val start: Int + val end: Int + if (firstVisible > lastFirstVisible) { + start = firstVisible + visibleCount + end = start + maxPreloadCount + preload(start, end, context) + } else if (firstVisible < lastFirstVisible) { + start = firstVisible + end = start - maxPreloadCount + preload(start, end, context) + } + lastFirstVisible = firstVisible + } + + private fun preload(from: Int, to: Int, context: Context) { + val totalItemCount = adapter.list.size + + var start: Int + var end: Int + if (from < to) { + start = max(lastEnd, from) + end = to + } else { + start = to + end = min(lastStart, from) + } + end = min(totalItemCount, end) + start = min(totalItemCount, Math.max(0, start)) + + if (from < to) { + // Increasing + for (i in start until end) { + adapter.list.getOrNull(i)?.preload(context) + } } else { - position - childCount + // Decreasing + for (i in end - 1 downTo start) { + adapter.list.getOrNull(i)?.preload(context) + } } - adapter.list.getOrNull(preloadPosition)?.preload(recyclerView.context) - lastPosition = position + lastStart = start + lastEnd = end } } From 636d0616bbdb75bb55780c373aa8e9dff10834e3 Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Wed, 21 Aug 2019 10:18:14 +0300 Subject: [PATCH 2/3] Preload logic updated --- .../omega_r/base/adapters/OmegaListAdapter.kt | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt b/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt index da5f752..6adaaf3 100644 --- a/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt +++ b/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt @@ -62,44 +62,31 @@ abstract class OmegaListAdapter : OmegaAdapter(), ListableAdapter ) : Watcher { private var lastEnd: Int = 0 - private var lastStart: Int = 0 private var lastFirstVisible = -1 override fun bindPosition(position: Int, recyclerView: RecyclerView) { val layoutManager = recyclerView.layoutManager as? LinearLayoutManager ?: return val context = recyclerView.context val firstVisible = layoutManager.findFirstVisibleItemPosition() - val lastVisible = layoutManager.findLastVisibleItemPosition() - val visibleCount = lastVisible - firstVisible - val start: Int - val end: Int + val from: Int + val to: Int if (firstVisible > lastFirstVisible) { - start = firstVisible + visibleCount - end = start + maxPreloadCount - preload(start, end, context) + from = lastEnd + to = from + maxPreloadCount + preload(from, to, context) } else if (firstVisible < lastFirstVisible) { - start = firstVisible - end = start - maxPreloadCount - preload(start, end, context) + from = firstVisible + to = from - maxPreloadCount + preload(from, to, context) } lastFirstVisible = firstVisible } private fun preload(from: Int, to: Int, context: Context) { - val totalItemCount = adapter.list.size - - var start: Int - var end: Int - if (from < to) { - start = max(lastEnd, from) - end = to - } else { - start = to - end = min(lastStart, from) - } - end = min(totalItemCount, end) - start = min(totalItemCount, Math.max(0, start)) + val size = adapter.list.size + val start = max(0, min(from, size)) + val end = max(0, min(to, size)) if (from < to) { // Increasing @@ -112,8 +99,6 @@ abstract class OmegaListAdapter : OmegaAdapter(), ListableAdapter adapter.list.getOrNull(i)?.preload(context) } } - - lastStart = start lastEnd = end } From 397c5e67360f4b98916c6a219189b14635d5055c Mon Sep 17 00:00:00 2001 From: roman_tcaregorodtcev Date: Wed, 21 Aug 2019 10:57:47 +0300 Subject: [PATCH 3/3] preload logic depends on bindPosition --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +-- .../omega_r/base/adapters/OmegaListAdapter.kt | 29 ++++++++----------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/build.gradle b/build.gradle index 9efd19c..01d09e4 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.android.tools.build:gradle:3.5.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3c063af..3196519 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed May 08 11:14:06 MSK 2019 +#Wed Aug 21 10:45:33 MSK 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt b/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt index 6adaaf3..e583544 100644 --- a/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt +++ b/lib/src/main/java/com/omega_r/base/adapters/OmegaListAdapter.kt @@ -1,6 +1,7 @@ package com.omega_r.base.adapters import android.content.Context +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -61,32 +62,28 @@ abstract class OmegaListAdapter : OmegaAdapter(), ListableAdapter private val maxPreloadCount: Int = 4 ) : Watcher { - private var lastEnd: Int = 0 - private var lastFirstVisible = -1 + private var lastBindPosition = -1 override fun bindPosition(position: Int, recyclerView: RecyclerView) { - val layoutManager = recyclerView.layoutManager as? LinearLayoutManager ?: return val context = recyclerView.context - val firstVisible = layoutManager.findFirstVisibleItemPosition() - val from: Int val to: Int - if (firstVisible > lastFirstVisible) { - from = lastEnd - to = from + maxPreloadCount + if (position > lastBindPosition) { + from = position + 1 + to = from + maxPreloadCount - 1 preload(from, to, context) - } else if (firstVisible < lastFirstVisible) { - from = firstVisible - to = from - maxPreloadCount + } else if (position < lastBindPosition) { + from = position - 1 + to = from - maxPreloadCount + 1 preload(from, to, context) } - lastFirstVisible = firstVisible + lastBindPosition = position } private fun preload(from: Int, to: Int, context: Context) { val size = adapter.list.size - val start = max(0, min(from, size)) - val end = max(0, min(to, size)) + val start = max(0, min(from, size - 1)) + val end = max(0, min(to, size - 1)) if (from < to) { // Increasing @@ -95,13 +92,11 @@ abstract class OmegaListAdapter : OmegaAdapter(), ListableAdapter } } else { // Decreasing - for (i in end - 1 downTo start) { + for (i in end downTo start) { adapter.list.getOrNull(i)?.preload(context) } } - lastEnd = end } - } } \ No newline at end of file