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). .
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 ...
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:
Exemple de projet POC disponible ici
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 .
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.
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.
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.