Astraport
12.07.2012, 13:20
Требуется в List вывести итемы и для каждого вывести звездочки в зависимости от рейтинга.
Делаю так. Компонент звезды с тремя состояниями - полная, половина, пустая звезда.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="24" height="25">
<s:states>
<s:State name="full"/>
<s:State name="half"/>
<s:State name="empty"/>
</s:states>
<s:Image left="0" top="0" source.empty="@Embed('images/stars_empty.png')" source.full="@Embed('images/stars_full.png')" source.half="@Embed('images/stars_half.png')"/>
</s:Group>
Сам рендерер (там в нем много всего, лишнее убрал):
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%"
creationComplete="itemrenderer1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import components.Star;
override public function set data(value:Object):void {
if(value != null) {
super.data = value;
//buildStars(Number(value.rating));
}
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
protected function buildStars (rating:Number):void
{
trace ('rating ' + rating);
for (var i:int = 0; i < 5; i++){
var star:Star = new Star();
if (i < rating){
star.currentState = 'full';
} else if (i > rating) {
star.currentState = 'empty';
} else {
star.currentState = 'half';
}
stars.addElement(star);
}
}
protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void
{
for (var i:int = 0; i < 5; i++){
var star:Star = new Star();
if (i < data.rating){
star.currentState = 'full';
} else if (i > data.rating) {
star.currentState = 'empty';
} else {
star.currentState = 'half';
}
stars.addElement(star);
}
}
]]>
</fx:Script>
<s:HGroup id="stars" width="100%" height="100%" gap="3" verticalAlign="middle"/>
</s:ItemRenderer>
В рендерер приходит значение rating, которое может быть не целым в диапазоне от 0 до 5.
Если я строю звезды как buildStars(Number(value.rating)); то при прокрутке листа звезды добавляются до бесконечности. Если строю через itemrenderer1_creationCompleteHandler, то звезд как положено пять, но их значение при прокрутке постоянно меняется.
Когда-то с подобным успешно боролся, но сейчас не могу вспомнить как именно.
Ну и нужен совет, как все же правильно менять состояния звезд чтобы выводить половинку звезды, если рейтинг будет допустим 3,84.
Добавлено через 5 минут
Можно конечно при каждом вызове buildStars (rating:Number) удалять все элементы из группы stars, но мне кажется это плохой, ресурсоемкий вариант, т. к. для мобил.
Добавлено через 23 минуты
Нашел похожий пример http://www.switchonthecode.com/tutorials/flex-using-item-renderers
Так что все нормально, но и там удаление/создание при каждом скроллинге - не хорошо.
Делаю так. Компонент звезды с тремя состояниями - полная, половина, пустая звезда.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="24" height="25">
<s:states>
<s:State name="full"/>
<s:State name="half"/>
<s:State name="empty"/>
</s:states>
<s:Image left="0" top="0" source.empty="@Embed('images/stars_empty.png')" source.full="@Embed('images/stars_full.png')" source.half="@Embed('images/stars_half.png')"/>
</s:Group>
Сам рендерер (там в нем много всего, лишнее убрал):
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="100%"
creationComplete="itemrenderer1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import components.Star;
override public function set data(value:Object):void {
if(value != null) {
super.data = value;
//buildStars(Number(value.rating));
}
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
protected function buildStars (rating:Number):void
{
trace ('rating ' + rating);
for (var i:int = 0; i < 5; i++){
var star:Star = new Star();
if (i < rating){
star.currentState = 'full';
} else if (i > rating) {
star.currentState = 'empty';
} else {
star.currentState = 'half';
}
stars.addElement(star);
}
}
protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void
{
for (var i:int = 0; i < 5; i++){
var star:Star = new Star();
if (i < data.rating){
star.currentState = 'full';
} else if (i > data.rating) {
star.currentState = 'empty';
} else {
star.currentState = 'half';
}
stars.addElement(star);
}
}
]]>
</fx:Script>
<s:HGroup id="stars" width="100%" height="100%" gap="3" verticalAlign="middle"/>
</s:ItemRenderer>
В рендерер приходит значение rating, которое может быть не целым в диапазоне от 0 до 5.
Если я строю звезды как buildStars(Number(value.rating)); то при прокрутке листа звезды добавляются до бесконечности. Если строю через itemrenderer1_creationCompleteHandler, то звезд как положено пять, но их значение при прокрутке постоянно меняется.
Когда-то с подобным успешно боролся, но сейчас не могу вспомнить как именно.
Ну и нужен совет, как все же правильно менять состояния звезд чтобы выводить половинку звезды, если рейтинг будет допустим 3,84.
Добавлено через 5 минут
Можно конечно при каждом вызове buildStars (rating:Number) удалять все элементы из группы stars, но мне кажется это плохой, ресурсоемкий вариант, т. к. для мобил.
Добавлено через 23 минуты
Нашел похожий пример http://www.switchonthecode.com/tutorials/flex-using-item-renderers
Так что все нормально, но и там удаление/создание при каждом скроллинге - не хорошо.