web-dev-qa-db-fra.com

Pourquoi le défilement régulier de RecyclerView ne fonctionne-t-il pas bien avec certaines classes d'Interpolator?

Contexte

Dans le but de faire un bref aperçu des éléments sur un RecyclerView horizontal, nous souhaitons une animation semblable à un rebond, qui commence à une position donnée et se termine au début du RecyclerView (par exemple, du point 3 au point 0). .

Le problème

Pour une raison quelconque, toutes les Interpolator classes que j'ai essayées (illustration disponible ici ) ne semblent pas permettre aux éléments de sortir de RecyclerView ou de rebondir dessus.

Plus spécifiquement, j'ai essayé OvershootInterpolator, BounceInterpolator et quelques autres similaires. J'ai même essayé AnticipateOvershootInterpolator. Dans la plupart des cas, il effectue un simple défilement, sans effet spécial. Sur AnticipateOvershootInterpolator, il ne défile même pas ...

Ce que j'ai essayé

Voici le code du POC que j'ai créé pour montrer le problème:

MainActivity.kt

class MainActivity : AppCompatActivity() {
    val handler = Handler()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val itemSize = resources.getDimensionPixelSize(R.dimen.list_item_size)
        val itemsCount = 6
        recyclerView.adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
                val imageView = ImageView(this@MainActivity)
                imageView.setImageResource(Android.R.drawable.sym_def_app_icon)
                imageView.layoutParams = RecyclerView.LayoutParams(itemSize, itemSize)
                return object : RecyclerView.ViewHolder(imageView) {}
            }

            override fun getItemCount(): Int = itemsCount

            override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            }
        }
        val itemToGoTo = Math.min(3, itemsCount - 1)
        val scrollValue = itemSize * itemToGoTo
        recyclerView.post {
            recyclerView.scrollBy(scrollValue, 0)
            handler.postDelayed({
                recyclerView.smoothScrollBy(-scrollValue, 0, BounceInterpolator())
            }, 500L)
        }
    }
}

activity_main.xml

<androidx.recyclerview.widget.RecyclerView
    Android:id="@+id/recyclerView" xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto" Android:layout_width="match_parent"
    Android:layout_height="@dimen/list_item_size" Android:orientation="horizontal"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

fichier gradle

apply plugin: 'com.Android.application'
apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions'

Android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-Android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.0-rc02'
    implementation 'androidx.core:core-ktx:1.0.0-rc02'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
    implementation 'androidx.recyclerview:recyclerview:1.0.0-rc02'
}

Et voici une animation sur l'apparence de BounceInterpolator, qui, comme vous pouvez le constater, ne rebondit pas du tout:

 enter image description here

Exemple de projet POC disponible ici

La question

Pourquoi cela ne fonctionne-t-il pas comme prévu et comment puis-je résoudre ce problème?

RecyclerView peut-il fonctionner correctement avec Interpolator pour le défilement?


EDIT: il semble que ce soit un bogue, car je ne peux utiliser d’interpolateur "intéressant" pour le défilement RecyclerView, aussi j’en ai rapporté le résultat ici .

15
android developer

Vous devez activer le bounce overscroll.

L'une des solutions possibles est d'utiliser https://github.com/chthai64/overscroll-bouncy-Android

Incluez-le dans votre projet

implementation 'com.chauthai.overscroll:overscroll-bouncy:0.1.1'

Et dans votre POV, changez RecyclerView dans activity_main.xml en com.chauthai.overscroll.RecyclerViewBouncy

<?xml version="1.0" encoding="utf-8"?>
<com.chauthai.overscroll.RecyclerViewBouncy
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:id="@+id/recyclerView"
    Android:layout_width="match_parent"
    Android:layout_height="@dimen/list_item_size"
    Android:orientation="horizontal"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

Après ce changement, vous verrez rebondir dans votre application.

0
dilix

Comme je l'ai dit, honnêtement, je ne m'attendrais pas à ce qu'un Release Candidate (recyclerview:1.0.0-rc02 dans votre cas) fonctionne correctement sans que cela pose de problèmes, car il est déjà en cours de développement.

  • L'utilisation de bibliothèques tierces peut fonctionner, mais je ne le pense pas vraiment, car elles viennent d'introduire des dépendances androidx et qu'elles sont déjà en développement etpas assez stablespour être utilisées par d'autres développeurs.

Mise à jour La réponse des développeurs Google:

Nous avons transmis cela à l'équipe de développement et mettrons à jour ce problème avec plus d'informations à mesure qu'elles deviennent disponibles.

Donc, il vaut mieux attendre les nouvelles mises à jour. 

0
ʍѳђઽ૯ท