Проблема при попытке динамического создания навигации с вкладками и динамическим текстом.
-
18-09-2019 - |
Вопрос
Привет всем, я создаю навигацию с вкладками из XML-файла.Однако по какой-то причине мой цикл создает текстовые поля только для активной вкладки и последней вкладки. (в данном случае 4-я вкладка).
> Вы можете просмотреть мой Flash здесь.< (Я включил границы текстового поля)
Мои проблемы:
1. Активная вкладка (вкладка светлого цвета) имеет неправильный размер в зависимости от ширины текстового поля.
2. Мой цикл почему-то пропускает 2 средние вкладки, но правильно устанавливает 4-ю вкладку.
Заголовки вкладок XML:
- Это первая вкладка
- 2-я вкладка
- Третья вкладка
- Четвертая и последняя вкладка
Кажется, что 2-я и 3-я вкладки имеют правильный размер, но, как вы увидите ниже, я получаю ошибку при попытке отследить текст 2-й и 3-й вкладки.
♥ Обновление: Добавлен весь класс TabMenu в надежде решить эту проблему :)Теперь я считаю, что именно в этом заключается моя проблема:
// tabNamer creates the active & default textfields
tabNamer(tabNameActive, Fonts.ActiveTabText, tabData[0].id); // for ActiveTab
tabNamer(tabNameDefault, Fonts.DefaultTabText, tabData[i].id); // for DefaultTabs
tabNamer это функция, содержащая только textField, и я считаю, что продолжаю переопределять последний созданный textField, поэтому только четвертый и последний textField отображает текст.Есть ли способ динамически называть мои текстовые поля в цикле?
TabMenu.as (весь класс)
package com.leongaban.TEN.ui
{
import flash.display.DisplayObject;
import flash.display.LineScaleMode;
import flash.display.JointStyle;
import flash.display.MovieClip;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.events.TimerEvent;
import com.leongaban.TEN.ui.*;
import com.leongaban.TEN.Global;
import com.leongaban.TEN.model.*;
public class TabMenu extends Sprite
{
private const position :Number = 0;
private var tabNameDefault:TextField = new TextField();
private var tabNameActive :TextField = new TextField();
private var backing :Shape = new Shape();
private var tabData :Array = [];
private var tabArray :Array = [];
private var bgColor :uint = 0xF6F6F6; //0xE8E7E7;
private var borderColor :uint = 0xCCCCCC;
private var borderSize :uint = 1;
private var sizeW :uint;
private var sizeH :uint;
private var topShadow :MovieClip;
private var tileShadow :MovieClip;
private var sideShadowL :MovieClip;
private var sideShadowR :MovieClip;
public function TabMenu():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
addChild(backing);
addChild(topShadow);
}
public function drawTabMenu(w, h, color, videoHDiff, ypos):void
{
for (var i in Global.xml..tab) {
tabData.push( {
id:Global.xml..tab[i].@id,
video:Global.xml..tab[i].vid,
title:Global.xml..tab[i].title} );
//trace("TAB TITLES: "+tabData[i].id);
}
//trace("FIRST TAB DATA : "+tabData[0].id[0]+"\n"+tabData[0].video);
sizeW = w;
sizeH = h;
topShadow = new EmptyMov();
tileShadow = new TileShadow();
sideShadowL = new SideShadowL();
sideShadowR = new SideShadowR();
sideShadowR.x = (sizeW-16) - sideShadowR.width;
tileShadow.width = sizeW-16;
topShadow.addChild(tileShadow);
topShadow.addChild(sideShadowL);
topShadow.addChild(sideShadowR);
backing.graphics.beginFill(bgColor);
backing.graphics.lineStyle(borderSize, borderColor);
backing.graphics.drawRect(position, position, sizeW-17, videoHDiff);
backing.graphics.endFill();
backing.y = tileShadow.height - 1;
//DRAW THE TABS -------------
for (i in tabData)
{
//trace("TAB TITLES: "+tabData[i].id);
var tab :MovieClip = new TabDefault();
var active :MovieClip = new TabActive();
tabArray.push(tab);
//tab.video = tabData[i].video;
//tab.title = tabData[i].title;
tab.addChild(active); // add active tab movieclip to default tab movieclip
// tabNamer creates the active & default textfields
tabNamer(tabNameActive, Fonts.ActiveTabText, tabData[0].id); // for ActiveTab
tabNamer(tabNameDefault, Fonts.DefaultTabText, tabData[i].id); // for DefaultTabs
i < 1 ? active.visible = true : active.visible = false;
//i < 1 ? tab.addChild(tabNameActive) : tab.addChild(tabNameDefault);
i < 1 ? tabArray[0].addChild(tabNameActive) : tabArray[i].addChildAt(tabNameDefault,2);
//tabArray[i].addChildAt(tabNameDefault,2);
//tab.addChild(tabNameDefault);
//if (i < 1) { tab.addChild(tabNameActive) }
trace("i = "+i);
trace("tabArray["+i+"].getChildAt(2) = "+tabArray[i].getChildAt(2).text);
trace("tabNameDefault.text = "+tabNameDefault.text);
// resize the tab background to textfield
tab.y = topShadow.y + 5;
// if first size to active textfield + 10 : if not size to default textfield + 10
tab.width = i < 1 ? tabNameActive.width + 10 : tabNameDefault.width + 10;
tab.x = i < 1 ? 10 : tabArray[(i-1)].x + (tabArray[(i-1)].width + 3);
//tab.active = i < 1 ? tab.active = true : tab.active = false;
topShadow.addChild(tab);
tab.mouseChildren = false;
tab.buttonMode = true;
tab.addEventListener(MouseEvent.CLICK, tabClick);
}
// set default thumbnails here
//trace("tabData[0].id : "+tabData[0].id.@id+"\r");
//trace("tabData[0].video: "+"\r"+tabData[0].video+"\r");
//trace("tabData[0].titles : "+tabData[0].titles+"\r");
}
private function tabNamer(textfield, textFormat, tabText):void
{
//trace("TabNamer called");
textfield.defaultTextFormat = textFormat;
textfield.border = false;
textfield.embedFonts = false;
textfield.gridFitType = "SUBPIXEL";
textfield.sharpness = 100;
textfield.antiAliasType = flash.text.AntiAliasType.ADVANCED;
textfield.autoSize = TextFieldAutoSize.CENTER;
textfield.selectable = false;
textfield.mouseEnabled = false;
textfield.x = 10;
textfield.y = 4;
textfield.text = tabText;
}
private function tabClick(e:MouseEvent = null):void
{
for (var i in tabArray) {
//tabArray[i].active = false;
tabArray[i].getChildAt(1).visible = false;
}
//e.target.active = true;
e.target.getChildAt(1).visible = true;
trace("Text for button clicked: "+e.target.getChildAt(2).text+"\r");
//trace("THUMBNAILS FOR TAB: " + e.target.video);
// pass the video data to the thumbnail class
}
}
}
функция tabNamer
private function tabNamer(textfield, textFormat, tabText):void
{
//trace("TabNamer called");
textfield.defaultTextFormat = textFormat;
textfield.border = true;
textfield.embedFonts = false;
textfield.gridFitType = "SUBPIXEL";
textfield.sharpness = 100;
textfield.antiAliasType = flash.text.AntiAliasType.ADVANCED;
textfield.autoSize = TextFieldAutoSize.CENTER;
textfield.selectable = false;
textfield.mouseEnabled = false;
textfield.x = 10;
textfield.y = 4;
textfield.text = tabText;
}
Функция tabClick
private function tabClick(e:MouseEvent = null):void
{
for (var i in tabArray) {
//tabArray[i].active = false;
tabArray[i].getChildAt(1).visible = false;
}
//e.target.active = true;
e.target.getChildAt(1).visible = true;
trace("Text for button clicked: "+e.target.getChildAt(2).text+"\r");
//trace("THUMBNAILS FOR TAB: " + e.target.video);
// pass the video data to the thumbnail class
}
Это следы от функции создания вкладок (функция класса)
i = 0
tabArray[0].getChildAt(2) = This is first tab
tabNameDefault.text = This is first tab
i = 1
tabArray[1].getChildAt(2) = 2nd Tab
tabNameDefault.text = 2nd Tab
i = 2
tabArray[2].getChildAt(2) = The 3rd Tab
tabNameDefault.text = The 3rd Tab
i = 3
tabArray[3].getChildAt(2) = The 4th and last tab
tabNameDefault.text = The 4th and last tab
Это следы, которые я получаю, когда нажимаю на вкладки (Я пытаюсь найти 2-е и 3-е текстовые поля)
//Clicked Tab 1
Text for button clicked: This is first tab
//Clicked Tab 2
RangeError: Error #2006: The supplied index is out of bounds.
at flash.display::DisplayObjectContainer/getChildAt()
at com.leongaban.ui::TabMenu/tabClick()
//Clicked Tab 3
RangeError: Error #2006: The supplied index is out of bounds.
at flash.display::DisplayObjectContainer/getChildAt()
at com.leongaban.ui::TabMenu/tabClick()
//Clicked Tab 4
Text for button clicked: The 4th and last tab
Весь день ломал над этим голову :( надеялся на какой-нибудь совет, подсказку или чувак, вот почему!:)
Решение
Проблема в том, что вы повторно используете TextField.tabNameActive ссылается на одно и то же текстовое поле в цикле.
Я предполагаю, что ваше текстовое поле tabNameActive находится на сцене.Если это так, вам необходимо сделать следующее:
1) Удалите tabNameActive со сцены.
2) Перейдите в свою библиотеку и найдите tabNameActive.Щелкните правой кнопкой мыши и выберите «Свойства».Установите флажок «Экспортировать по первому кадру».
3) Появится окно.Теперь укажите идентификатор класса «TabNameActiveClass».
4) Вернитесь к своему коду.В цикле for добавьте это под объявлениями переменных.
var tab:MovieClip = new TabDefault();
var active:MovieClip = new TabActive();
var tabNameActive:TabNameActiveClass = new TabNameActiveClass();
Этот должен работа.
Резюме:По сути, вы создаете свой текст как класс и создаете его разные экземпляры в цикле.Прямо сейчас вы просто повторно используете экземпляр, и во время создания он фактически перемещается с вкладки 1 на вкладку 4.
EDTIED в ответ на комментарии ниже:
Удалите из определения класса:
private var tabNameDefault:TextField = new TextField();
private var tabNameActive :TextField = new TextField();
Затем добавьте свой цикл:
var tab:MovieClip = new TabDefault();
var active:MovieClip = new TabActive();
var tabNameActive:TextField = new TextField();
var tabNameDefault:TextField = new TextField();
Другие советы
Мне кажется, что ваша проблема заключается в повторном использовании TextField. tabNameDefault
.Вот что делает ваш код:
- Установите текст
tabNameActive
иtabNameDefault
к данным первой вкладки - Добавлять
tabNameActive
как дочерний элемент первой вкладки - Установите текст
tabNameActive
иtabNameDefault
к данным второй вкладки - Добавлять
tabNameDefault
как дочерний элемент второй вкладки - Установите текст
tabNameActive
иtabNameDefault
к данным третьей вкладки - Добавлять
tabNameDefault
как дочерний элемент третьей вкладки. Это удалит его со второй вкладки. - Установите текст
tabNameActive
иtabNameDefault
к данным четвертой вкладки - Добавлять
tabNameDefault
как дочерний элемент четвертой вкладки, удалив его из третьей вкладки.
Вы не весь код показали.В частности, я не вижу нигде, где создаются текстовые поля.Я предполагаю, что вы создаете только два текстовых поля (tabNameActive и tabNameDefault).Где-то внутри цикла for должно быть что-то вроде «new TextField()», создающего вкладки.
Исправьте, пожалуйста, отступы в коде, его очень трудно читать повсюду.Также я не рекомендую использовать конструкцию a?b:c там, где в ней нет необходимости, особенно в тех случаях, когда вы используете ее для выполнения операторов вместо выражений.