• 移动开发技巧总结


    一.CaltrainTimes案列分析:

    http://www.adobe.com/cn/devnet/flex/articles/caltrain-times-story.html
    1.确定设计分辨率,并由设计师给出相应的PSD档
    2.合并图层割图
    3.根据缩放导出不同的DPI,及相应的文件夹
    4.UI设计,以保证效率、用户体验、不同DPI下正确渲染
    5.程序开发,以整合数据和需求,并解决多DPI问题
    6.优化,完成MXML到AS的手工转换
    7.根据不同的平台导出相应的发布包

    //////////////////////////////////////////////////////////////////////////////////////////

    二.DPI设计原则

    分辨率是像素高度乘宽度得到的数值,即设备支持的像素总数;DPI是每平方英寸的点数,即设备
    屏幕上的像素密度。在Flex中利用applicationDPI/runtimeDPI和动态布局的概念来完成对不同的
    DPI的设计

    多平台适配技巧
    1.用矢量图或MultiDPIBitmapSource位图(由runtimeDPI决定),后者利用BitmapImage和Image配合
    使用,但是无法显示对特定DPI不显示图像
    2.文本的字体大小缩放至分辨率相符的大小
    3.使用动态布局,避免使用约束布局,不要手动来缩放(可以使用锚点)
    4.使用@media来定义不同OS和DPI下的样式属性,结合and/not/or(,)操作符,对属性os-platform和
    application-dpi筛选
    5.皮肤使用DPI值来确定资源(switch/case)。由FXG文件定义的皮肤都适用于目标设备
    6.不要显式设置应用程序的高和宽,由SystemManager.screen获取其值

    方案选择:
    1.自动缩放:设置applicationDPI值,并创建针对该DPI值的单组外观和视图/组件布局,对于位图资源,
    采用MultiDPIBitmapSource来进行视频,无需考虑矢量资源和文本,不要使用@media规则,反复测试
    2.非自动缩放:不设置applicationDPI值(会被设成rumtimeDPI),创建可根据不同DPI动态调整的单组外观和布局,
    使用@media规则,反复测试
    可以在Application中用runtimeDPI和applicationDPI,或View中用FlexGlobals.topLevelApplication.runtimeDPI
    和FlexGlobals.topLevelApplication.applicationDPI计算比例后得到运行时资源目录

    重写默认DPI映射
    Application类的runtimeDPIProvider属性指向RuntimeDPIProvider类的子类。并在子类中重写runtimeDPI getter并
    添加用于提供自定义DPI映射的逻辑

    //////////////////////////////////////////////////////////////////////////////////////////

    三.移动皮肤

    Mobile主题里的皮肤使用一个新的基类MobileSkin,它扩展了UIComponent,
    1.状态:MobileSkin不再用State类及子类,而是手工的在代码里处理状态改变,例如SetProperty和AddChild
    2.布局:MobileSkin不是一个Group,不能再用约束布局(HorizontalLayout/VerticalLayout/BasicLayout),其内容在
    代码中人工的布局,放到layoutContents()中,该函数会在updateDisplayList()中被调用
    3.图形:Mobile主题中皮肤的图形由编译过的FXG和用于绘制的ActionScript代码构成
    4.文本:使用Label/TextInput/TextArea,对于不使用的MXML情况,采用TextField和StyleableTextField
    5.皮肤:由于改变了MXML的状态、布局和图形,故用MXML已经没有什么优势,故最好用ActionScript编写皮肤
    6.避免使用的全局样式:rollOverColor/borderAlpha/borderColor/cornerRadius/dropShadowVisible
    7.避免使用的组件:ComboBox/DropDownList/NumericStepper/ToggleButton/VideoDisplay/VideoPlayer/VSlider/Panel/TabBar/TitleWindow

    //////////////////////////////////////////////////////////////////////////////////////////

    四.原生神器

    其包括:StageText/StageVideo/StageWebView,具有相同的优点,即拥有原生的性能及功能,但也有一点共同的弱点,它们都不
    是DisplayObject;StageText使用viewPort定义及在Stage上的位置,并渲染在顶层,另外,不能滚动控件所在的视图,也不能使用嵌入字体,
    不能对基于StageText的控件使用自定义大小调解决方法是调用,不过利用drawViewPortToBitmapData接口来实现类似RenderTarget的功能

    //////////////////////////////////////////////////////////////////////////////////////////

    五.移动字体

    在移动版本中,如果要使用字体应该使用Spark中TextInput/TextArea,它们默认采用的是基于StageText的移动皮肤StageTextInputSkin和
    StageTextAreaSkin,但是不支持类似TLF一样的高级特性;不过如果要获得这些特性,可以请将其外观类指向基于TextField的TextInputSkin和
    TextAreaSkin;Label控件使用FTE,它的性能不如优化后的文本控件TextInput和TextArea,但是它不使用TLF,性能上又优于RichText和
    RichEditableText控件;在创建基于AS的项呈示器时,使用StyleableTextField,对于基于MXML的组件,仍可以使用Label;但是对于嵌入字体,
    不能使用基于CFF的Label,而应该采用基于TextField的TextArea,如要一个非交互式多行文本,应将editable属性设为false,举个嵌入式的例子:
    <fx:Style>
    @namespace s "library://ns.adobe.com/flex/spark";
    @font-face {
    src: url("../assets/MyriadWebPro.ttf");
    fontFamily: myFontFamily;
    embedAsCFF: false;
    }
    .customStyle {
    fontFamily: myFontFamily;
    fontSize: 24;
    skinClass: ClassReference("spark.skins.mobile.TextAreaSkin");
    }
    </fx:Style>
    <s:TextArea id="ta1" styleName="customStyle" text="This is a TextArea control that uses an embedded font."/>

    //////////////////////////////////////////////////////////////////////////////////////////

    六.移动设备过渡效果

    通过ViewNavigator容器类,navigator对象来控制过渡效果,目前定制的效果有CrossFadeViewTransition、FlipViewTransition、
    SlideViewTransition、CrossFadeViewTransition,常用的方法有pushView/popView/popToFirstView/popAll/replaceView等;
    可以给navigator对象defaultPopTransition和defaultPushTransition的默认行为,还可以加入缓动类Bounce/Linear/Sine来给
    效果赋值easer和duration属性;其过渡效果的基类有captureStartValues/prepareForPlay/play/captureEndValues由调用者来
    触发,如果需要重载即可。


    //////////////////////////////////////////////////////////////////////////////////////////

    七.闪屏

    闪屏很简单而且适用于所有Flex Application类(Application、ViewNavigatorApplication和TabbedViewNavigatorApplication)。要想启用这个
    特性,设置splashScreenImage为一个嵌入的图像,设置splashScreenMinimumDisplayTime的时间,设置splashScreenScaleMode的缩放模式(none/
    stretch/zoom/letterbox);同时他还支持基于不同DPI来返回不同的闪屏图形文件,只需继承SplashScreen类,并重写getImageClass方法,并将其
    类名赋予实现preloader,例子如下:
    public class MultiDPISplashScreen extends SplashScreen
    {
    [Embed(source="assets/splash160.png")]
    private var SplashImage160:Class;

    [Embed(source="assets/splash240.png")]
    private var SplashImage240:Class;

    [Embed(source="assets/splash320.png")]
    private var SplashImage320:Class;

    public function MultiDPISplashScreen()
    {
    super();
    }

    override mx_internal function getImageClass(dpi:Number, aspectRatio:String):Class
    {
    if (dpi == DPIClassification.DPI_160)
    return SplashImage160;
    else if (dpi == DPIClassification.DPI_240)
    return SplashImage240;
    else if (dpi == DPIClassification.DPI_320)
    return SplashImage320;
    return null;
    }
    }

    //////////////////////////////////////////////////////////////////////////////////////////

    八.多平台开发

    在不同的平台下进行开发,具有显著的平台差异,包括:硬件按钮、可用的屏幕面积、活版印刷、软键盘、文本输入、颜色的深浅,
    每个平台供应商都具有其独特的人机接口规范(HIG),称为UI规范:
    IOS:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/index.html
    Android:http://developer.android.com/design/index.html
    故设计应用程序中很重要的一点是,您必须清楚何时以及如何将特定于平台的不同点考虑在内,在一些特殊情况下需要创建特定平台
    的外观和样式
    1.使用CSS媒体查询,利用@media及os-platform属性
    2.主题的使用,以共享库(frameworks/themes/Mobile/mobile.swc)为基础,覆盖不同平台下的移动主题swc,结合并重写default.css
    覆盖原有SDK的的CSS文件(frameworks/projects/mobiletheme/defaults.css)

    //////////////////////////////////////////////////////////////////////////////////////////

    九.构建同时适合Web和Mobile的应用程序

    1.用应用程序框架,将Web和Mobile公用逻辑部分抽象成Basecode
    2.采用Spark和Mobile皮肤,并且尽量采用FXG和AS绘图代码,避免使用MXML
    3.采用Spark的List和DataGrid创建快速列表,并且不建议使用默认Flex ItemRenderer类,而应该采用优化过的LabelItemRenderer和
    IconItemRenderer类,效率更高
    4.对于平板,可以使用SplitViewNavigator,内容是两个ViewNavigators。一个用于大纲视图,一个用于细节视图

    ////////////////////////////////////////////////////////////////////////////////////////// 

    十.处理设备朝向

    如果要处理朝向问题,要打开属性<autoOrients>true</autoOrients>,并对stage对象注册两种事件类型:StageOrientationEvent.ORIENTATION_CHANGE
    和StageOrientationEvent.ORIENTATION_CHANGING,在回调函数中取得StageOrientationEvent对象的deviceOrientation属性,如下:
    1.StageOrientation.DEFAULT:默认的舞台朝向
    2.StageOrientation.ROTATED_LEFT:向左旋转
    3.StageOrientation.ROTATED_RIGHT:向右旋转
    4.StageOrientation.UNKNOWN:未知的舞台朝向
    5.StageOrientation.UPSIDE_DOWN:上下颠倒

    //////////////////////////////////////////////////////////////////////////////////////////

    十一.View生命流程

    View的生命期的控制是通过destructionPolicy属性来控制的;如果要在View1的基础上激活View2,其正常的流程为:
    1.删除View1以响应屏幕变化的removing事件
    2.View2添加到display列表的added事件
    3.View2的add事件
    4.View2的creationComplete事件
    5.View1的viewDeactivate事件
    6.Display列表中删除View1的removed事件
    7.View2的viewActivate事件
    还可以覆盖View的createReturnObject方法,从弹出的视图中返回数据:
    data = navigator.poppedViewReturnedObject.object;

    //////////////////////////////////////////////////////////////////////////////////////////

    十二.移动常用技巧

    1.如果你要风格化颜色,文本,定位,图标等方面的内容,使用CSS就可以了。
    2.如果你想创建一个有更多图像元素的外观,可以使用FXG,自定义皮肤,和画图。
    3.如果你想设置不同分辨率的设备上的皮肤,你可以使用CSS媒体过滤器或FXG中装载的支持各种分辨率的特殊皮肤类别
    4.如果要隐藏动作条组件或标签组件,可以利用actionBarVisible和tabBarVisible属性
    5.如果想要响应tabbedNavigator的按钮切换事件,可以注册IndexChangeEvent.CHANGE事件
    6.如果你想要修改标签组件,显示在上部,可首先从相应SDK版本的frameworks/projects/mobiletheme/src/spark/skins/mobile
    找到相应的类型的皮肤,比如TabbedViewNavigatorSkin.as,将其拷贝到我们的资源路径并改名,再结合修改后的路径名修改皮肤
    文件中的package,并声明CSS样式s|TabbedViewNavigator,其skinClass属性为修改好的路径名和文件名,最后修改皮肤文件中的
    layoutContents来重新进行布局

    //////////////////////////////////////////////////////////////////////////////////////////

    十三.持久化

    View容器通过使用View.data属性来支持内存持久化机制。当切换所新视图,会自动保存现有视图的data属性。当重新回到该视图时,将恢复该视图的data属性,
    故该机制可以在运行时维护视图的状态信息;可在ViewNavigatorApplication和TabbedViewNavigatorApplication中,将persistNavigatorState属性设置为true,
    会使用PersistenceManager往FxAppCache的本地共享对象中,写入applicationVersion和navigatorState属性,前者对应于application.xml中的应用程序版本,
    后者对应于当前ViewNavigator的堆栈;在persistNavigatorState属性为false时,可以调用load方法以初始化PeristenceManager,用setProperty和getProperty
    方法实现属性的设置和获取,并用save方法以将数据写入磁盘,来实现自己的持久化机制,此时在navigatorStateSaving事件的处理函数中调用preventDefault()
    方法,来取消将应用程序状态保存至磁盘的操作。在navigatorStateLoading事件的处理函数中调用preventDefault()方法可以取消在重新启动应用程序时加载状态,
    具体如下:
    1.重写View类的serializeData和deserializeData方法
    2.使用支持的数据类型:Number、String、Vector、Object、uint、int和Boolean
    3.如果是自定义的数据类,应在应用程序的preinitialize事件,调用flash.net.registerClassAlias()来注册
    4.如果定义复杂的类(使用非内置数据类型),则必须将数据转换为受支持的类型(String)。如果类定义了任何私有变量,则不会自动持久保存这些变量。要在持久化
    机制中支持复杂的类,该类必须实现flash.utils.IExternalizable接口。并实现writeExternal()和readExternal()方法以保存和恢复类的实例

    //////////////////////////////////////////////////////////////////////////////////////////

    十四.ActionBar

    其区域包括:导航区域,标题区域,操作区域,可以在ViewNavigatorApplication、ViewNavigator和View容器中设置用于定义ActionBar 控件内容的属性。View容器的
    优先级最高,其次是ViewNavigator,再其次是ViewNavigatorApplication容器:
    1.导航区域,用navigationContent属性定义组件, navigationLayout属性定义布局
    2.标题区域,用title属性定义标题字符串,用titleContent属性定义组件, titleLayout属性定义布局
    3.操作区域,用actionContent属性定义组件, actionLayout属性定义布局
    注意,可以调用navigator的方法hideActionBar来隐藏ActionBar,还可以重写方法createActionBarHideEffect和createActionBarShowEffect来更改显示和隐藏效果,
    可以调用tabbedNavigator的方法hideTabBar来隐藏TabBar,通过重写方法createTabBarHideEffect和createTabBarShowEffect来更改显示和隐藏效果


    //////////////////////////////////////////////////////////////////////////////////////////

    十五.移动设备可以使用组件限制

    1.可以完全使用的新组件(Spark):ActionBar/BusyIndicator/Callout/CalloutButton/DataSpinner/SpinnerList/SpinnerListContainer/TabViewNavigator/
    TabViewNavigatorApplication/ToggleSwitch/View/ViewMenu/ViewNavigator/ViewNavigatorApplication
    2.可以使用的具有皮肤的组件(Spark):Button/CheckBox/DataGroup/Group/HGroup/VGroup/TileGroup/Image/BitmapImage/Label/List/RadioButton/
    SkinnableContainer/Scroller/TextArea/TextInput
    3.其他的Spark Skinnable组件:建议不要使用,这些组件不具有适用于移动设备主题的外观
    4.其他的Spark Containner组件:建议不要使用,包括:DataGrid/RichEditableText/RichText
    5.可以使用的Spacer组件(Halo)
    6.可以使用的图表组件(Halo),当存在性能隐患
    7.除5和6以外,其他的Halo组件是不能使用

    //////////////////////////////////////////////////////////////////////////////////////////

    十六.处理滚动

    如果屏幕的可见区域无法显示全部内容,应用程序将显示滚动条,使用Scroller控件可以在应用程序中添加滚动条。其他组件(Spark List)支持滚动,因此您无需使用Scroller
    组件;在基于桌面或浏览器的应用程序中,点击区域是滚动条的可见区域,在移动设备应用程序中,都会隐藏滚动栏,这样可使应用程序使用屏幕的全屏宽度和高度;其具备以
    下几个术语:
    1.内容:指整个组件区域,可能会仅显示部分内容。
    2.视口:当前可见的组件内容区域中的一部分。
    3.拖动:用户触摸可滚动区域,然后移动手指以便内容沿手势移动时发生的触摸手势。
    4.速度:拖动手势的移动速率和方向。以沿 X 和 Y 轴每毫秒的像素为单位。
    5.抛开:用户在拖动手势达到特定速度后抬起手指时的拖动手势,此时可滚动内容仍继续移动。
    6.跳动:拖动或抛开手势可以将可滚动组件的视口移至组件内容之外。然后,视口显示空白区域。当您释放手指或抛开速度达到零时,视口将跳跃回其静止点,并且视口有内容
    填充。移动随着视口接近静止点而减慢,因此能平稳停止。
    在基于Scroller的组件中,可以使用pageScrollingEnabled和scrollSnappingMode属性,前者用来控制移动时基于像素还是基于页面的,后者用来控制吸附的方式,包括
    leadingEdge/center/trailingEdge;如果要对TextInput和TextArea使用Scroller,要采用基于TextField的皮肤,而不是默认的StageText皮肤;在与其交互的过程中,程序必
    须区分用户的意图,用户是要与控件交互还是要进行滚动(Button举例):
    1.设置touchDelay属性,指定延迟期,可以确保用户正在选择Button而不是尝试滚动屏幕
    2.延迟期内,手指必须移动约0.08英寸的距离,该手势才会被解释为滚动操作,此时Button不会识别该交互
    3.延迟期后,Button识别该交互,更改其外观;此时如果移动手指的距离可以大于0.08,Button恢复正常状态,启动滚动操作
    注意,以上的判断都是基于mouseDown事件,故对于该事件,用户的预期行为不明确(可能组件交互,可能滚动),建议侦听click或mouseUp事件,而不是mouseDown事件;有时我们
    要自定义滚动行为,就要了解其行为:滚动操作开始时发出信号,分派mouseDown事件的组件将分派冒泡的touchInteractionStarting事件。如果未取消该事件,组件将分派冒泡的
    touchInteractionStart事件,当组件检测到touchInteractionStart事件时,不得尝试响应用户手势,如果组件不希望启动滚动,组件可以在touchInteractionStarting事件的事
    件处理函数中调用preventDefault方法,完成滚动操作之后,分派mouseDown事件的组件将分派冒泡的touchInteractionEnd组件

  • 相关阅读:
    git更新代码
    git标签
    git分支
    命令连接redis
    sql语句
    rm -rf无法删除文件解决方法
    lombda 使用记录
    centos查看磁盘空间大小
    CentOS7 防火墙Firewall常用命令
    安装rabbitmq
  • 原文地址:https://www.cnblogs.com/fuland/p/3629940.html
Copyright © 2020-2023  润新知