当前位置:  编程技术>移动开发
本页文章导读:
    ▪支持各种尺码的屏幕        支持各种尺寸的屏幕 支持各种尺寸的屏幕 课程内容 使用”wrap_content”和”match_parent” 使用RelativeLayout 使用尺寸限定符 使用Smallest-width限定符 使用Layout别名 使用方向限定符 使用.........
    ▪ 关于WP7中的90M内存限制有关问题及设计原则        关于WP7中的90M内存限制问题及设计原则 一. 在wp7中,程序所使用内存不能超过90M, 否则会自动退出 二. 如果一个page没有被释放,那么它所包含的所有控件资源都不会被垃圾收集.      在wp.........
    ▪ intent传arrayList报 Parcel: unable to marshal value异常       intent传arrayList报 Parcel: unable to marshal value错误 解决办法之一是:ArrayList<Bean>中的Bean要实现序列化接口 ......

[1]支持各种尺码的屏幕
    来源: 互联网  发布时间: 2014-02-18
支持各种尺寸的屏幕
支持各种尺寸的屏幕
课程内容
  • 使用”wrap_content”和”match_parent”
  • 使用RelativeLayout
  • 使用尺寸限定符
  • 使用Smallest-width限定符
  • 使用Layout别名
  • 使用方向限定符
  • 使用Nine-patch格式图片
  • 您还应该阅读
    • 支持多种屏幕
    动手试试

    下载示例项目

    NewsReader.zip

    该课程将告诉您如何通过如下方式来支持各种尺寸的屏幕:

    • 确保您的布局可以改变大小来填充整个屏幕
    • 根据屏幕的配置来显示不同的布局
    • 确保布局应用到对应的屏幕上
    • 使用能正确缩放的图片
    使用”wrap_content”和”match_parent”

    要确保您的布局是弹性的并且可以适应各种尺寸的屏幕,你应该使用"wrap_content" 和"match_parent" 来设置一些控件的宽高。如果使用"wrap_content" ,控件的宽度和高度将会设置为能够显示该控件内容的最小尺寸;而当你使用"match_parent" (在API level 8之前被称之为"fill_parent" )的时候,控件的高度和宽度将和父控件的大小一样。

    当使用"wrap_content"   和  "match_parent" 来代替具体的大小数字的时候,您的控件要么只使用能显示其内容的最小尺寸或者填充整个能用的空间。下面是一个示例:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout android:layout_width="match_parent"
                      android:id="@+id/linearLayout1"
                      android:gravity="center"
                      android:layout_height="50dp">
            <ImageView android:id="@+id/imageView1"
                       android:layout_height="wrap_content"
                       android:layout_width="wrap_content"
                       android:src="/blog_article/@drawable/logo/index.html"
                       android:paddingRight="30dp"
                       android:layout_gravity="left"
                       android:layout_weight="0" />
            <View android:layout_height="wrap_content"
                  android:id="@+id/view1"
                  android:layout_width="wrap_content"
                  android:layout_weight="1" />
            <Button android:id="@+id/categorybutton"
                    android:background="@drawable/button_bg"
                    android:layout_height="match_parent"
                    android:layout_weight="0"
                    android:layout_width="120dp"
                    />
        </LinearLayout>
     
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
     

    注意示例中的代码是如何使用  "wrap_content"   和  "match_parent"   而不是使用具体的数值来指定控件的大小。这样布局就可以根据不同的屏幕尺寸和方向来自适应显示界面。

    下图是该布局在横向或者纵向的情况下的显示情况,注意 控件的宽度和高度自动的适应屏幕的尺寸:

    新闻阅读程序在横向(左)和纵向(右)的显示

    使用 RelativeLayout

    通过"wrap_content"   和  "match_parent"   以及嵌套使用多个LinearLayout 您可以实现各种复杂的布局。然而,LinearLayout 不允许精确的控制子控件之间的关系;在LinearLayout 里面的控件只是一个挨着一个去布局的。如果您不想让控件只是排成一行或者一列,使用  RelativeLayout 是一个更好的选择,该布局可以指定子控件之间的相对位置。例如,你可以指定一个子控件位于屏幕的左边而另外一个位于屏幕的右边。

    示例

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/label"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Type here:"/>
        <EditText
            android:id="@+id/entry"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/label"/>
        <Button
            android:id="@+id/ok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/entry"
            android:layout_alignParentRight="true"
            android:layout_marginLeft="10dp"
            android:text="OK" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/ok"
            android:layout_alignTop="@id/ok"
            android:text="Cancel" />
    </RelativeLayout>
     

    下图显示了该布局在QVGA屏幕上的界面

    在QVGA屏幕上的截图(小屏幕)

    在大屏幕上的界面

    在WSVGA屏幕上的截图(大屏幕)

    注意:尽管控件的大小改变了, 但是他们之间的相对位置通过RelativeLayout.LayoutParams 定义为一样。

    使用尺寸限定符

    您可以通过前面的方法实现各种各样的自适应布局和相对布局。但是这种布局只是通过把控件拉伸或者拉伸控件周围的空间,对于大小不同的屏幕并没有提供最优的用户体验。因此,您的程序应该不仅仅只是实现自适应的布局,还应该根据不同的屏幕配置分别提供更加友好的布局。通过配置限定符 可以实现这个优化,这样在运行时系统会自动的选择适合当前设备的布局和资源(例如:针对不同屏幕使用不同的布局)。

    例如,很多程序在大屏幕设备上使用“两个窗口”布局模式(程序可以在一个窗口中显示一个列表而在另外一个窗口中显示列表中选中的内容)。平板设备和电视剧的屏幕足够用来同时显示两个窗口,但是手机设备就只能分别显示他们了。因此,要实现这种布局,您需要使用如下的文件:

    • res/layout/main.xml , 单个窗口(默认)布局
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
     
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
     
    • res/layout-xlarge/main.xml , 两个窗口布局
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="400dp"
                  android:layout_marginRight="10dp"/>
        <fragment android:id="@+id/article"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.ArticleFragment"
                  android:layout_width="fill_parent" />
    </LinearLayout>
     

    注意上面的文件夹中的xlarge 限定符,这个文件夹里面的布局只会用到屏幕尺寸为超级大(例如:10寸的平板)的设备中。其他的布局(没有限定符的)将会用于小屏幕的设备中。

    使用 Smallest-width 限定符

    在Android 3.2之前的版本上,开发者可能有点郁闷,应为之前的“large”限定符包含的尺寸太宽泛了,例如 Dell Streak、Galaxy 平板、以及7寸的平板。但是很多开发者都想在这个范围内根据不同的具体屏幕尺寸来显示不同的布局(例如 5寸和7寸的设备)。在Android 3.2版本中引入 “Smallest-width”限定符就是为了解决这个问题的。

    Smallest-width限定符可以让你指定目标设备的最少屏幕尺寸(单位是dp)。例如,普通的7寸平板的最小宽度是600dp,因此如果你希望你的程序在这种尺寸的屏幕上使用两个窗口(小于该尺寸的屏幕使用一个窗口),那么您可以使用上面的两个布局文件,只要把xlarge 限定符替换为sw600dp 即可, 可以看出在3.2+版本中,对屏幕的限定更加详细了。

    • res/layout/main.xml , 一个窗口(默认)布局
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
     
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
     
    • res/layout-sw600dp/main.xml , 两个窗口布局
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="400dp"
                  android:layout_marginRight="10dp"/>
        <fragment android:id="@+id/article"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.ArticleFragment"
                  android:layout_width="fill_parent" />
    </LinearLayout>
     

    上面的代码意味着,只要最小屏幕宽度大于等于600dp的设备都会使用layout-sw600dp/main.xml 这个两个窗口布局,而小于该尺寸的设备就用layout/main.xml 一个窗口的布局。

    但是,这样在3.2之前的版本没法使用,因为他们不认识sw600dp 这个限定符,这样您还是要同时使用xlarge 限定符。这样您的res/layout-xlarge/main.xml   文件和res/layout-sw600dp/main.xml 文件的内容是一样的。在下一个小节中,您会看到一种技术可以让你避免这种内容一样的布局文件出现。

    使用布局别名

    上面看到的Smallest-width限定符只适用于3.2+的设备,因此您还需要同时使用(small, normal,large and xlarge)这些限定符来让您的程序运行在3.2之前的系统中。例如:如果你想设计一个界面,在手机中显示一个窗口,而在7寸平板或者更大的设备中显示两个窗口,您需要这些布局文件:

    • res/layout/main.xml: 单个窗口布局
    • res/layout-xlarge: 两个窗口布局
    • res/layout-sw600dp: 两个窗口布局

    后面的两个布局文件是一样的,一个是用于3.2+设备的;一个用于之前的设备的。

    为了避免这种布局文件的重复,并且维护起来也很麻烦,您可以使用别名文件。例如您可以定义如下的布局文件:

    • res/layout/main.xml , 单个窗口布局
    • res/layout/main_twopanes.xml , 两个窗口布局

    布局文件内容:

     

    • res/values-xlarge/layout.xml
    <resources>
        <item name="main" type="layout">@layout/main_twopanes</item>
    </resources>
     
    • res/values-sw600dp/layout.xml
    • <resources>
          <item name="main" type="layout">@layout/main_twopanes</item>
      </resources>
       
    • 这两个文件内容是一样的,但是他们实际上并没有定义布局。他们仅仅设置了main 为main_twopanes 的一个别名。既然该布局文件有xlarge   和  sw600dp 这两个限定符,这样不管系统的版本是3.2之前的还是之后的,满足尺寸要求的都会使用该布局。
    使用方向限定符

    有些布局在横向和纵向屏幕中都表现很好,但是有些可以稍作修改从而提升用户体验。在新闻阅读示例程序中,下面展示了在不同的屏幕尺寸和屏幕方向中使用的布局:

    • 小屏幕 纵向:   带Logo的单个窗口
    • 小屏幕 横向:   带Logo的单个窗口
    • 7寸平板, 纵向:   有动作条的单个窗口
    • 7寸平板, 横向:   有动作条的两个宽窗口
    • 10寸平板, 纵向:   有动作条的两个窄窗口
    • 10寸平板, 横向:   有动作条的两个宽窗口

    每个布局都在res/layout/ 目录中定义了一个布局文件。通过布局别名来影射的不同的配置项中的:

    res/layout/onepane.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
     
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
     

    res/layout/onepane_with_bar.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout android:layout_width="match_parent"
                      android:id="@+id/linearLayout1"
                      android:gravity="center"
                      android:layout_height="50dp">
            <ImageView android:id="@+id/imageView1"
                       android:layout_height="wrap_content"
                       android:layout_width="wrap_content"
                       android:src="/blog_article/@drawable/logo/index.html"
                       android:paddingRight="30dp"
                       android:layout_gravity="left"
                       android:layout_weight="0" />
            <View android:layout_height="wrap_content"
                  android:id="@+id/view1"
                  android:layout_width="wrap_content"
                  android:layout_weight="1" />
            <Button android:id="@+id/categorybutton"
                    android:background="@drawable/button_bg"
                    android:layout_height="match_parent"
                    android:layout_weight="0"
                    android:layout_width="120dp"
                    />
        </LinearLayout>
     
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="match_parent" />
    </LinearLayout>
     

    res/layout/twopanes.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="horizontal">
        <fragment android:id="@+id/headlines"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.HeadlinesFragment"
                  android:layout_width="400dp"
                  android:layout_marginRight="10dp"/>
        <fragment android:id="@+id/article"
                  android:layout_height="fill_parent"
                  android:name="com.example.android.newsreader.ArticleFragment"
                  android:layout_width="fill_parent" />
    </LinearLayout>
     

    res/layout/twopanes_narrow.xml :

    现在所有的布局文件都定义好了,只要使用配置限定符做好影射即可,通过布局别名很容易实现:

    res/values/layouts.xm

    <resources>
        <item name="main_layout" type="layout">@layout/onepane_with_bar</item>
        <bool name="has_two_panes">false</bool>
    </resources>
     

    res/values-sw600dp-land/layouts.xml

    <resources>
        <item name="main_layout" type="layout">@layout/twopanes</item>
        <bool name="has_two_panes">true</bool>
    </resources>
     

    res/values-sw600dp-port/layouts.xml

    <resources>
        <item name="main_layout" type="layout">@layout/onepane</item>
        <bool name="has_two_panes">false</bool>
    </resources>
     

    res/values-xlarge-land/layouts.xml

    <resources>
        <item name="main_layout" type="layout">@layout/twopanes</item>
        <bool name="has_two_panes">true</bool>
    </resources>
     

    res/values-xlarge-port/layouts.xml

    <resources>
        <item name="main_layout" type="layout">@layout/twopanes_narrow</item>
        <bool name="has_two_panes">true</bool>
    </resources>
     

    使用Nine-patch格式图片

    支持不同尺寸的屏幕也意味着在不同的屏幕上使用不同大小的图片。例如,一个按钮的背景图片在任何尺寸的按钮上都应该是差不多的。

    如果您在能改变大小的控件上使用同一个图片,你将会发现这些图片将会被缩放,看起来有点毛毛糙糙。而Android系统中的nine-patch格式图片就解决了这个问题。

    要让一个普通的图片转换为nine-patch格式的,如下图(为了清楚的演示,该图被放大了4倍)

    button

    通过Android SDK中的  draw9patch 工具(在tools/ 目录中)编辑,详情请参考这篇详细介绍 ,如下图:

    button.9.png

    注意 边框上的黑色像素点。左边和上边的黑点定义了图片可以被拉伸的地方,右边和下边的黑点定义了控件内容可以显示的地方。

    同时也要注意图片的扩展名为.9.png 。只有这种格式的图片系统才认为是nine-patch格式的。

    如果您使用该图片作为控件的背景(代码android:background="@drawable/button" ),系统会自动的拉伸响应的地方,如下图所示:

    button.9.png 在各种尺寸下被拉伸的情况


        
    [2] 关于WP7中的90M内存限制有关问题及设计原则
        来源: 互联网  发布时间: 2014-02-18
    关于WP7中的90M内存限制问题及设计原则

    一. 在wp7中,程序所使用内存不能超过90M, 否则会自动退出

    二. 如果一个page没有被释放,那么它所包含的所有控件资源都不会被垃圾收集.

         在wp7中操作图像资源是很费内存的,如果内存超过90M,你的程序就挂了,而我们在XAML文件中定义的Image控件,由于属于静态资源,所以你不可能在后台CS代码中对它们进行image.source = null 操作,我试过,没有用,除非你把Image控件的定义放在CS代码中,这样你执行image.source = null 操作或者将Image控件从LayoutRoot中卸掉:LayoutRoot.Children.Remove(Image), 那么这个image就会被垃圾收集。

    因此,对于在XAML文件中定义的图像控件来说,要想释放这些图像所占用的内存,唯一时刻只能是离开这个Page的时刻。所以,一条重要原则就是尽量不要将一个包含大量图像控件的page作为你的MainPage,因为这个Page会等到整个程序结束(exit)的时候才会被释放,你想想,在整个程序运行过程中,这些内存一直被占用着,一旦你再开一个包括许多图像的page,或者你load了其他东西到内存里,你的内存使用很可能会超过90M。

    所以建议就是:

      1.如果程序有主界面的话,尽量不要在主界面上放太多图像控件。或者说不要将一个拥有大量图像的page作为main page。

      2.尽可能将需要播放动画并包含大量图像的page单独做成一个page,播放完毕或者用完就离开这个page

      3.Panorama 的background 如果设置成图像image的话,会消耗大量内存,一般24M左右,而且跟是否是jpg或png, 跟图像大小和复杂度也没关系, 我做过试验,唯一能降低内存消耗的方法是讲panorama的高度(height)减小,比如减小一般,那么内存消耗也会减小一般,因为它只绘制了一半在界面上嘛。

       你可能会想到将panorama的背景设置成渐变,我试过,这样也会消耗17M内存。如果设置成单色(solid color brush),大约消耗2-3M左右。 唯一不会消耗内存的就是:no background.

       因此,请在选用Panorama之前,好好检查一下你的程序当前已经消耗了多少内存。余下的内存还够不够你load 一个panorama大胃王。

      4.听说Pivot也是个让人又爱又恨的东西,在你加了很多tab到一个pivot中,而且图像又太多时,它也可能挂。 不过具体情况我还没试,以后再说。

     

    另外,附送一段代码,让你知道在WP7中,如何让你知道每个Page何时被释放?

            #if(DEBUG)
            /// <summary>
            /// Add a finalizer to check for memory leaks
            /// </summary>
            ~YourPage()
            {
                System.Diagnostics.Debug.WriteLine("Finalizing " + this.GetType().FullName);
            }
            #endif

    你可以将这段代码添加到你的每一个page中,记得修改这个析构函数的名称哦。 那么当这个page被析构的时候,就会在output控制台里看到。

     

    看来很多同学都想知道为什么会有这个限制,那么我就补充一下吧:

    这是因为Windows Phone 7的应用程序认证要求规定的,5.2.5规定,任何应用程序不得使用超过90 MB的内存,除非手机的可用内存超过256 MB。

    下面是英文详细说明:

    5.2.5 Memory Consumption
    An application must not exceed 90 MB of RAM usage, except on devices that have more than 256 MB of memory. You can use the DeviceExtendedProperties class to query the amount of memory that is available on the device and modify the application behavior at runtime to take advantage of additional memory. For more information, see the DeviceExtendedProperties class in MSDN.
    The DeviceTotalMemory value returned by DeviceExtendedProperties indicates the physical RAM size in bytes. This value is less than the actual amount of device memory. For an application to pass certification, Microsoft recommends that the value returned by ApplicationPeakMemoryUsage is less than 90 MB when the DeviceTotalMemory is less than or equal to 256 MB.

    所以说这个脑残的规定实际上是防止你的程序无限制的使用内存从而拖慢整个系统的运行,包括多个程序之间的切换,微软这次就是想让windows phone 7的用户体验更加流畅,由于目前推出的所有型号的wp7手机的RAM都是256MB, 因此如果以后出的手机RAM增加了,可能就不会有这个限制了。


        
    [3] intent传arrayList报 Parcel: unable to marshal value异常
        来源: 互联网  发布时间: 2014-02-18
    intent传arrayList报 Parcel: unable to marshal value错误

    解决办法之一是:ArrayList<Bean>中的Bean要实现序列化接口


        
    最新技术文章:
    ▪Android开发之登录验证实例教程
    ▪Android开发之注册登录方法示例
    ▪Android获取手机SIM卡运营商信息的方法
    ▪Android实现将已发送的短信写入短信数据库的...
    ▪Android发送短信功能代码
    ▪Android根据电话号码获得联系人头像实例代码
    ▪Android中GPS定位的用法实例
    ▪Android实现退出时关闭所有Activity的方法
    ▪Android实现文件的分割和组装
    ▪Android录音应用实例教程
    ▪Android双击返回键退出程序的实现方法
    ▪Android实现侦听电池状态显示、电量及充电动...
    ▪Android获取当前已连接的wifi信号强度的方法
    ▪Android实现动态显示或隐藏密码输入框的内容
    ▪根据USER-AGENT判断手机类型并跳转到相应的app...
    ▪Android Touch事件分发过程详解
    ▪Android中实现为TextView添加多个可点击的文本
    ▪Android程序设计之AIDL实例详解
    ▪Android显式启动与隐式启动Activity的区别介绍
    ▪Android按钮单击事件的四种常用写法总结
    ▪Android消息处理机制Looper和Handler详解
    ▪Android实现Back功能代码片段总结
    ▪Android实用的代码片段 常用代码总结
    ▪Android实现弹出键盘的方法
    ▪Android中通过view方式获取当前Activity的屏幕截...
    ▪Android提高之自定义Menu(TabMenu)实现方法
    ▪Android提高之多方向抽屉实现方法
    ▪Android提高之MediaPlayer播放网络音频的实现方法...
    ▪Android提高之MediaPlayer播放网络视频的实现方法...
    ▪Android提高之手游转电视游戏的模拟操控
     


    站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3