PhilFlash

Flex 4.5 Mobile - Sauver/Restaurer la position dans une List

Traduire/Translate (by Google) : English - Espagnol - Deutsch

Obtenir les sources listSaveRestorePosition.fxp (projet Flex 4.5)

En Flex 4.5, vous pouvez utiliser des listes avec une vue Détail pour afficher la vue détaillée d'un élément.

Mais, lorsque vous revenez à la liste, vous allez "perdre" l'élément sélectionné.

En effet, dans Flex mobile, une View est construite à chaque affichage de la vue. Ce mécanisme par défaut repositionne donc la liste sur les premiers éléments visibles de la liste (et pas sur l'élément que vous aviez préalablement sélectionné).

Ce problème est connu. Par exemple, sur le blog de Flexponential, vous trouverez un article permettant de restaurer la position des barres de scroll. Mais, si vous modifier le mode landscape/portrait de votre téléphone/tablette, ceci ne fonctionne plus.

Voici une méthode qui va permettre de visualiser l'élément sélectionné en première position.

La méthode s'inspire de l'article de Flexponential. Lors de la création d'une nouvelle vue, la vue précédente est détruite. Cependant, la propriété data n'est pas détruite. Elle va être utilisée pour sauver des informations.

On va donc utiliser cette propriété data pour sauver l'indice de l'élément sélectionné avec la méthode viewDeactivate. Lors du retour à la liste, on va utiliser la méthode creationComplete de la vue pour restaurer l'élément sélectionné.

On pourrait utiliser ensureIndexIsVisible pour rendre visible un élément. Mais généralement, celui-ci se trouve en fin de liste. Le code suivant positionne l'élément sélectionné au début de la liste.

Ce code fonctionne pour des listes verticales.

Source code
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
  3. xmlns:s="library://ns.adobe.com/flex/spark"
  4. title="List Position"
  5. initialize="onInitialize()"
  6. viewDeactivate="savePosition()"
  7. creationComplete="restorePosition()"
  8. >
  9. <fx:Declarations>
  10. <s:ArrayCollection id="dataAC" />
  11. </fx:Declarations>
  12. <fx:Script>
  13. <![CDATA[
  14. import model.Customer;
  15. import model.IwModel;
  16. import mx.effects.AnimateProperty;
  17. import spark.components.DataGroup;
  18. import spark.events.IndexChangeEvent;
  19.  
  20. private function onInitialize():void
  21. {
  22. dataAC.source = IwModel.instance.customers.source;
  23. }
  24. protected function list_changeHandler(event:IndexChangeEvent):void
  25. {
  26. navigator.pushView(DetailView, list.selectedItem);
  27. }
  28.  
  29. private function savePosition():void
  30. {
  31. if (data == null) data = new Object();
  32. data.selectedIndex = list.selectedIndex;
  33. }
  34. private function restorePosition():void
  35. {
  36. if (data == null) return;
  37. var selectedIndex:int = data.selectedIndex as int;
  38. if (selectedIndex >= 0)
  39. {
  40. // use callLater for a bug of List
  41. // For no animation, use callLater(scrollToIndex, [selectedIndex,0]);
  42. callLater(scrollToIndex, [selectedIndex]);
  43. }
  44. }
  45.  
  46. private function scrollToIndex(index:int, animationDuration:int = 500):void
  47. {
  48. if (!list.layout) return;
  49. var dataGroup:DataGroup = list.dataGroup;
  50. if (index != -1)
  51. {
  52. var spDelta:Point = list.dataGroup.layout.getScrollPositionDeltaToElement(index);
  53. if (spDelta == null)
  54. {
  55. // top of list
  56. var bounds:Rectangle = dataGroup.layout.getElementBounds(index);
  57. spDelta = new Point(bounds.x, bounds.y);
  58. if (dataGroup.contentHeight < dataGroup.scrollRect.height)
  59. {
  60. spDelta.y = 0;
  61. }
  62. else if (spDelta.y > (dataGroup.contentHeight - dataGroup.scrollRect.height))
  63. {
  64. spDelta.y = dataGroup.contentHeight - dataGroup.scrollRect.height;
  65. }
  66. }
  67. else if ((spDelta != null) && (spDelta.y != 0))
  68. {
  69. if (spDelta.y > 0 && (spDelta.y + dataGroup.scrollRect.height - dataGroup.layout.getElementBounds(index).height) <= dataGroup.contentHeight)
  70. {
  71. var newY:Number = spDelta.y + dataGroup.scrollRect.height - dataGroup.layout.getElementBounds(index).height;
  72. // bottom of list
  73. if (newY > (dataGroup.contentHeight - dataGroup.scrollRect.height))
  74. {
  75. newY = dataGroup.contentHeight - dataGroup.scrollRect.height;
  76. }
  77. spDelta.y = newY;
  78. }
  79. }
  80. if (animationDuration <= 0)
  81. {
  82. dataGroup.verticalScrollPosition = dataGroup.verticalScrollPosition + spDelta.y;
  83. }
  84. else
  85. {
  86. // Animate the verticalScrollPosition value
  87. var animation:AnimateProperty = new AnimateProperty(dataGroup);
  88. animation.property = "verticalScrollPosition";
  89. animation.duration = animationDuration;
  90. animation.toValue = dataGroup.verticalScrollPosition + spDelta.y;
  91. animation.play();
  92. }
  93. }
  94. }
  95. ]]>
  96. </fx:Script>
  97. <s:List id="list" width="100%" height="100%" dataProvider="{dataAC}" change="list_changeHandler(event)">
  98. <s:itemRenderer>
  99. <fx:Component>
  100. <s:IconItemRenderer labelFunction="getLabel" messageFunction="getMessage" opaqueBackground="0xffffff">
  101. <fx:Script>
  102. <![CDATA[
  103. import model.Customer;
  104. protected function getLabel(o:Customer):String
  105. {
  106. return o.id + " " + o.firstname + " " + o.lastname;
  107. }
  108. protected function getMessage(o:Customer):String
  109. {
  110. return o.city;
  111. }
  112. ]]>
  113. </fx:Script>
  114. </s:IconItemRenderer>
  115. </fx:Component>
  116. </s:itemRenderer>
  117. </s:List>
  118. </s:View>

List Restore Position

Obtenir les sources listSaveRestorePosition.fxp (projet Flex 4.5)

 

 

xhtml   css   cc   508   aaa
Me connaître  |  Me contacter