![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
В общем-то все нормально работало, но какие-то обновления в Feathers сделали результат не стабильным.
Не буду давать свое старое, не рабочее решение. Вопрос прост: список, каждый итем имеет текст и кнопку (или картинку) в accessory "Удалить". Нужно по клику на этой картинке удалять итем. Весь вопрос как получить list.selectedIndex?
__________________
In Code We Trust |
|
|||||
|
у класса DefaultListItemRenderer есть свойство owner (feathers.controls.List),
в вашем классе доступ к нему super.owner.selectedIndex оно? |
|
|||||
|
Мой List не хочет обрабатывать ни CHANGE, ни TRIGGERED (через FeathersEventType.RENDERER_ADD) на accessory. В этом проблема. На label - пожалуйста, срабатывают, но на accessory - нет.
И наверное нужно было в первом посте указать, что хочется обойтись без кастомного итем рендерера. С ним все понятно. Но не хочется городить огород ради текстового списка в котором нужно только удалять некоторые записи.
__________________
In Code We Trust |
|
|||||
|
тач событие действительно слушается только для текстового объекта
protected function replaceAccessory(newAccessory:DisplayObject):void { ................................... if(this.accessory) { if(this.accessory is IFeathersControl) { if(!(this.accessory is BitmapFontTextRenderer)) { this.accessory.addEventListener(TouchEvent.TOUCH, accessory_touchHandler); |
|
|||||
|
не настолько крут в физерс, чтоб ответить на вопрос
но кроме наследования дефолтного рендера, никогда других способов не применял но там обычно стояли задачи сделать сильно отличающийся от дефолтного рендер, например с чекбоксами, несколько разных типов скинов, аватарок и функционалов и с индексами и т.д. проблем не было |
|
|||||
|
Если честно, то все это меня уже достало. Самому писать итем рендерер оказалось сложно, т. к. там у меня текст разной длины, нужно рендерер расширять, ресайзить.
На основе BaseDefaultItemRenderer получается ерунда тоже: если переписать его и диспатчить событие клика на accessory, то почему-то срабатывает и на всем остальном редерере тоже. Мне нужно чтобы по клику на Label было одно событие, по клику на accessory - другое. ShockWave512, покажи, плиз, как ты размещаешь в accesory, допустим, кнопку, которая при нажатии отправляет индекс списка, но при этом не вызывает других событий, а при нажатии на остальную часть рендерера, вызывается другое событие, которое тоже передает индекс?
__________________
In Code We Trust |
|
|||||
|
вообще не пользуюсь ацесори фичами, не помню почему, но полгода назад отказался, может по тем же причинам
// Кнопки просто добавлены на рендер _acceptButton.addEventListener( Event.TRIGGERED, acceptHandler ); _removeButton.addEventListener( Event.TRIGGERED, removeHandler ); // ----------------------------------------- private function removeHandler( event : Event = null ):void { owner.dataProvider.removeItem( _item ); // Ловим, разбираемся и удаляем рендер итем в родителе owner.dataProvider.dispatchEvent( new Event( Event.CHANGE, false, this.data ) ); // Индекс если что в поле index самого рендера } private function acceptHandler( event : Event = null ) : void { (this.data as DataVO).isAccepted = true; owner.dataProvider.dispatchEvent( new Event( Event.CHANGE, false, this.data ) ); } |
|
|||||
|
Так ты все же кастомный рендерер юзаешь? Я не смог добиться нормального ресайза, т. к. в зависимости от объемов текста он у меня должен увеличиваться по высоте. Это конечно можно, но, боюсь, окончательно погрязну.
Короче написал я костыль из костылей Работает, но очень неуютно на душе![]() Переписал свой BaseDefaultItemRenderer добавив пару строк чтобы asseccory диспатчил Event.TRIGGERED package renderers { import feathers.controls.List; import feathers.controls.renderers.BaseDefaultItemRenderer; import feathers.controls.renderers.IListItemRenderer; import feathers.controls.text.BitmapFontTextRenderer; import feathers.core.IFeathersControl; import feathers.events.FeathersEventType; import starling.display.DisplayObject; import starling.events.Event; import starling.events.Touch; import starling.events.TouchEvent; import starling.events.TouchPhase; public class MyItemRenderer extends BaseDefaultItemRenderer implements IListItemRenderer { public function MyItemRenderer() { super(); } /** * @private */ protected var _index:int = -1; /** * @inheritDoc */ public function get index():int { return this._index; } /** * @private */ public function set index(value:int):void { this._index = value; } /** * @inheritDoc */ public function get owner():List { return List(this._owner); } /** * @private */ public function set owner(value:List):void { if(this._owner == value) { return; } if(this._owner) { this._owner.removeEventListener(FeathersEventType.SCROLL_START, owner_scrollStartHandler); this._owner.removeEventListener(FeathersEventType.SCROLL_COMPLETE, owner_scrollCompleteHandler); } this._owner = value; if(this._owner) { const list:List = List(this._owner); this.isSelectableWithoutToggle = list.isSelectable; this.isToggle = list.allowMultipleSelection; this._owner.addEventListener(FeathersEventType.SCROLL_START, owner_scrollStartHandler); this._owner.addEventListener(FeathersEventType.SCROLL_COMPLETE, owner_scrollCompleteHandler); } this.invalidate(INVALIDATION_FLAG_DATA); } /** * @private */ override public function dispose():void { this.owner = null; super.dispose(); } override protected function replaceAccessory(newAccessory:DisplayObject):void { if(this.accessory == newAccessory) { return; } if(this.accessory) { this.accessory.removeEventListener(FeathersEventType.RESIZE, accessory_resizeHandler); this.accessory.removeEventListener(TouchEvent.TOUCH, accessory_touchHandler); if(this.accessory.parent == this) { //the accessory may have come from outside of this class. it's //up to that code to dispose of the accessory. in fact, if we //disposed of it here, we will probably screw something up, so //let's just remove it. this.accessory.removeFromParent(false); } } if(this.accessoryLabel && this.accessoryLabel != newAccessory) { //we can dispose this one, though, since we created it this.accessoryLabel.dispose(); this.accessoryLabel = null; } if(this.accessoryImage && this.accessoryImage != newAccessory) { this.accessoryImage.removeEventListener(Event.COMPLETE, loader_completeOrErrorHandler); this.accessoryImage.removeEventListener(FeathersEventType.ERROR, loader_completeOrErrorHandler); //same ability to dispose here this.accessoryImage.dispose(); this.accessoryImage = null; } this.accessory = newAccessory; if(this.accessory) { if(this.accessory is IFeathersControl) { if(!(this.accessory is BitmapFontTextRenderer)) { this.accessory.addEventListener(TouchEvent.TOUCH, accessory_touchHandler); } this.accessory.addEventListener(FeathersEventType.RESIZE, accessory_resizeHandler); } //added this line this.accessory.addEventListener(TouchEvent.TOUCH, accessory_touchHandler);//added this line this.addChild(this.accessory); } if(this.accessoryImage) { this.accessoryImage.delayTextureCreation = this._delayTextureCreationOnScroll && this._owner.isScrolling; } } override protected function accessory_touchHandler(event:TouchEvent):void { if(!this._isEnabled) { this.accessoryTouchPointID = -1; return; } if(!this.stopScrollingOnAccessoryTouch || this.accessory == this.accessoryLabel || this.accessory == this.accessoryImage) { //do nothing return; } if(this.accessoryTouchPointID >= 0) { var touch:Touch = event.getTouch(this.accessory, TouchPhase.ENDED, this.accessoryTouchPointID); if(!touch) { return; } this.accessoryTouchPointID = -1; } else //if we get here, we don't have a saved touch ID yet { touch = event.getTouch(this.accessory, TouchPhase.BEGAN); if(!touch) { return; } dispatchEvent(new Event(Event.TRIGGERED));//added this line this.accessoryTouchPointID = touch.id; } } } } this.myList = new List(); myList.dataProvider = LoadData.myListData; myList.itemRendererProperties.labelField = "text"; myList.itemRendererFactory = function():IListItemRenderer { var renderer:MyItemRenderer = new MyItemRenderer(); renderer.nameList.add(MyTheme.MY_LIST); return renderer; } myList.itemRendererProperties.accessoryFunction = function( item:Object ):DisplayObject { var img:Image = new Image(Main.assets.getTexture('delete')); img.addEventListener(TouchEvent.TOUCH, deleteItem); return img; } myList.addEventListener(Event.CHANGE, list2_scrollHandler); addChild(myList); private function deleteItem(e:TouchEvent):void { var point:int; var img:Image = e.target as Image; var touch:Touch =e.getTouch(img, TouchPhase.BEGAN); if(!touch) { return; } isDelete= true; } private function list2_scrollHandler(e:Event):void { if (isDelete){ //delete item isDelete = false; } else { //select item } } Юзаю Touch события на аксессуаре т. к., если вставить кнопку вместо Image и ловить TRIGGERED, то CHANGE у листа наступает раньше. Ну и тогда вместо удаления происходит выбор итема.
__________________
In Code We Trust |
|
|||||
|
при создании текста на рендере, можно получить его высоту, затем setSize(), должно работать, но возможно не будет работать virtualLayout, что плохо
а почему не DefaultListItemRenderer? List же пользует его |
![]() |
![]() |
Часовой пояс GMT +4, время: 23:35. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|