尝试使用动态文本动态创建选项卡式导航时出现问题
大家好,我正在从 XML 文件创建选项卡式导航。但是由于某种原因,我的循环仅为活动选项卡和最后一个选项卡创建文本字段(在本例中为第四个选项卡)。
>您可以在这里预览我的 Flash。 <(我打开了文本字段边框)
我的问题:
1.活动选项卡(浅色选项卡)未根据文本字段的宽度正确调整大小
2. 由于某种原因,我的循环跳过了 2 个中间选项卡,但正确设置了第四个选项卡。
XML 选项卡标题:
- 这是第一个选项卡
- 第二个选项卡
- 第三个选项卡
- 第四个也是最后一个选项卡
似乎第二个和第三个选项卡的大小正确,但正如您在下面进一步看到的,我在尝试追踪第二个和第三个选项卡的文本时收到错误。
♥ 更新:添加了整个 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 是一个仅包含文本字段的函数,我相信我一直覆盖最后一个文本字段,这就是为什么只有第四个也是最后一个文本字段显示文本。有没有办法在循环中动态命名我的文本字段?
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
这些是我单击选项卡时得到的痕迹(我试图找到第二个和第三个文本字段)
//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
一整天都在绞尽脑汁:(希望任何建议、提示或伙计,这就是原因:)
Hi everyone, I'm creating a tabbed navigation from an XML file. However for some reason my loop only creates textfields for the active tab and the last tab (in this case the 4th tab).
> You can preview my Flash here. < (I turned textfield borders on)
My Issues:
1. The Active Tab (light colored tab) does not size correctly based on the width of the textfield
2. My loop for some reason skips the 2 middle tabs, but correctly sets the 4th tab.
XML Tab titles:
- This is first tab
- 2nd Tab
- The 3rd Tab
- The 4th and last tab
It seems that the 2nd and 3rd tabs get sized correctly, but as you see further below, I get an error when trying to trace out the text of the 2nd and 3rd tab.
♥ Update: Added entire TabMenu class in hopes of getting this resolved :)
I now believe this is where my problem lies:
// 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 is a function containing just a textField, and I believe I keep overriding the last textField made, this is why only the 4th and last textField shows text. Is there a way to dynamically name my textFeilds are I loop?
TabMenu.as (Entire Class)
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 function
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 function
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
}
These are the traces from the create tabs function (class function)
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
These are the traces I get when I click the tabs (I'm trying to find the 2nd & 3rd textfields)
//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
Been raking my brain over this all day :( hoping for any advice, tips or dude that's why! :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题是您正在重用 TextField。 tabNameActive 在整个循环中引用相同的文本字段。
我的猜测是您的文本字段“tabNameActive”位于舞台上。如果是这种情况,您需要执行以下操作:
1) 从阶段中删除 tabNameActive
2) 转到您的库并找到 tabNameActive。右键单击并单击属性。选中“在第一帧导出”。
3) 出现一个窗口。现在给出一个类标识符“TabNameActiveClass”。
4)回到你的代码。在 for 循环中,将其添加到变量声明下方。
这应该可以工作。
回顾:基本上,您将文本作为一个类,并在循环中创建它的不同实例。现在,您只是重用该实例,它在创建过程中基本上从选项卡 1 移动到选项卡 4。
EDTIED 回应以下评论:
从类定义中删除:
然后添加循环:
The problem is that you are reusing the TextField. tabNameActive is referencing the same Text field through out the loop.
My guess is that your textfield 'tabNameActive' is on the stage. If that's the case, you need to do the following:
1) Delete the tabNameActive from the stage
2) Go to your library and find the the tabNameActive. Right-click and click properties. Check "Export on first frame".
3) A window shows up. Now give a class identifier "TabNameActiveClass".
4) Go back to your code. Within the for loop, add this below the variable declarations.
This should work.
Recap: Basically, you make your text as a class and make different instance of it in the loop. Right now, you are just reusing the instance and it basically gets moved from tab 1 to 4 during creation.
EDTIED in response to comments below:
Remove from your class definition:
Then add with your loop:
在我看来,您的问题是重用 TextField
tabNameDefault
。您的代码执行的操作如下:tabNameActive
和tabNameDefault
的文本设置为第一个选项卡的数据tabNameActive
添加为第一个选项卡Set 将tabNameActive
和tabNameDefault
的文本添加到第二个选项卡的数据中tabNameDefault
添加为第二个选项卡的子项tabNameActive< 的文本/code> 和
tabNameDefault
添加到第三个选项卡的数据tabNameDefault
添加为第三个选项卡的子选项。 这会将其从第二个选项卡中删除。tabNameActive
和tabNameDefault
的文本设置为第四个选项卡的数据tabNameDefault
作为第四个选项卡的子选项,将其从第三个选项卡中删除。It looks to me like your problem is reusing the TextField
tabNameDefault
. Here's what your code is doing:tabNameActive
andtabNameDefault
to the first tab's datatabNameActive
as a child of the first tabtabNameActive
andtabNameDefault
to the second tab's datatabNameDefault
as a child of the second tabtabNameActive
andtabNameDefault
to the third tab's datatabNameDefault
as a child of the third tab. This removes it from the second tab.tabNameActive
andtabNameDefault
to the fourth tab's datatabNameDefault
as a child of the fourth tab, removing it from the third tab.您还没有显示所有代码。具体来说,我没有看到任何创建文本字段的地方。我的猜测是您只创建两个文本字段(tabNameActive 和 tabNameDefault)。在 for 循环中应该有类似“new TextField()”的东西来创建选项卡。
请修复代码缩进,到处都是这样很难阅读。另外,我建议不要在不必要的地方使用 a?b:c 构造,特别是在使用它来执行语句而不是表达式的情况下。
You haven't shown all of the code. Specifically, I don't see anywhere that is creating the textfields. My guess is you only create two textfields (tabNameActive and tabNameDefault). There should be something like 'new TextField()' somewhere inside your for loop that creates the tabs.
Please fix the code indentation, it's very hard to read with it all over the place. Also I recommend against using the a?b:c construct where it's not necessary, especially in cases where you are using it to perform statements instead of expressions.