ListView Cell Translation manipulation affects other cells

Viewed 250

I'm working on a custom SwipeListView which allows to swipe cells to the left or to the right, currently only for Android. This works perfectly fine, but for some reason changing TranslationX of the Cell's ContentView affects other cells in the ListView. Every 8th cell changes it's TranslationX too (at least visually):

Swipe Bug

This is the line of code which results in this behavior:

mainContent.TranslationX = quota * Width + mainContentPositionX;

I've tried some possible solutions, none of them worked:

  • Try every different CachingStrategy for the ListView (RetainElement, RecycleElement, RecycleElementAndDataTemplate)
  • Run code on MainThread
  • After manipulating TranslationX, iterate through all other cells in my ListView and set their TranslationX to 0

I was sure the problem is that the cell is being reused and that's why it applies the TranslationX manipulation, but if it's that then I'm confused why using CachingStrategy=RetainElement doesn't solve the issue.

I will also we grateful for ideas which help be to debug this problem.


Edit

I implemented the SwipeListView feature for iOS and it works without any problems. Seems to be an Android issue.


Edit - Github Repository

I have added a sample Github Repository: https://github.com/Zure1/SwipeListView-Sample

Edit

I can now confirm that this is only a problem in Android. iOS works fine.

1 Answers

You are right in your analysis that the issue lies in item recycling. As you are changing the translation programmatically, the framework is not aware about your change and that you want it to be reverted so it keeps the translation as is. All the Caching Strategies involve item recycling including RetainElement. Recycling is better to stay enabled as it provides big performance gains.

A possible solution to your issue is to use data binding to set the TranslationX property and have the bound property on your ViewModel. This way the value reset whenever the control is recycled and bound to a new ViewModel. You can either introduce an integer property on your ViewModel and bind that to TranslationX or maybe the cleaner way is you introduce a Boolean property like IsSwipped and create a Data Trigger on that to set the translation as needed.

Related