Android Developers:针对电视优化布局

来源:互联网 发布:教师网络研修心得 编辑:程序博客网 时间:2024/06/05 09:21

当你的应用程序运行在一个电视上的时候,你应该假设用户坐在距离屏幕大约10英寸远的地方。这样的用户环境被作为10-foot UI被引用。为了给你的用户提供一个舒适和愉快的体验,你应该相应的设计和定制你的UI。 

 

这节课程向你展示如何通过以下方式,针对电视优化你的布局: 

  • 为横屏模式提供适当的布局资源。 

  • 确保文本和控件从一定距离看,足够大保证可见。 

  • 为高清电视屏幕提供高分辨率的位图和图标。 

 

设计横屏布局 

——————————————————————————————————————————————————————————————

电视屏幕总是在横屏方向,遵循这些提示来为对电视屏幕优化,构建横屏布局: 

  • 方式屏幕导航控制在屏幕的左侧或者右侧,为内容节省垂直空间。 

  • 分部分创建UI,通过使用Fragment,和使用如GridView视图组替代ListView来更好的利用横向屏幕空间。 

  • 使用如RelativeLayout或者LinearLayout视图组排列视图。它允许Android系统针对视图大小调整位置,对齐,长宽比和电视屏幕的像素密度。 

  • 在布局控件之间添加足够的边缘来避免一个凌乱的界面。 

 

例如,下面的布局是针对电视优化的: 


在这个布局中,控制控件在左侧。UI被现实在一个GridView中,它完美适应横屏方向。在这个布局中,GridView和Fragment的宽度和高度都是设置为动态的,所以它们能适应屏幕的分辨率。控制控件在运行时动态的添加到左侧。这个UI的布局文件是red/layout-land-large/photogrid_tv.xml。(这个布局文件被放置在layout-land-large是因为电视拥有横向的大屏幕。更多信息查阅Supproting Mutiple Screens。) 

 

res/layout-land-large/photogrid_tv.xml 

<RelativeLayout     android:layout_width="fill_parent"     android:layout_height="fill_parent" >     <fragment         android:id="@+id/leftsidecontrols"         android:layout_width="0dip"         android:layout_marginLeft="5dip"         android:layout_height="match_parent" />     <GridView                 android:id="@+id/gridview"         android:layout_width="wrap_content"         android:layout_height="wrap_content" /> </RelativeLayout> 

 

wie了在屏幕的左侧设置Action Bar选项,你也可以在你的应用程序中包含Left navigation bar library,来在屏幕的左侧设置Action选项,替代使用一个自定义的Fragment来添加控制控件: 

LeftNavBar bar = (LeftNavBarService.instance()).getLeftNavBar(this); 

 

当你有一个内容垂直滑动的Activity的时候,总是使用左侧导航栏;另一方面,你的用户必须滑动到内容的顶端,在内容视图和ActionBar之间进行切换。看Left navigation bar sample app,看到如何在你的应用中简单包含左导航栏。 

 

使文本和控件容易看见 

———————————————————————————————————————— 

在一个电视应用界面中的文本和控件,应该在一定距离内容易被看见和导航。遵循下面的这些提示是它们在一定的距离内更容易被看见: 

  • 精简文本,使用户能快速的扫描。 

  • 在一个黑暗的背景中使用高亮的文本。这种样式在电视中更容易阅读。 

  • 避免轻量级的字体,或者字体非常窄和粗。使用简单的sans-serif字体和anti-aliasing来郑强可读性。 

  • 使用Android的标准字体大小: 

<TextView         android:id="@+id/atext"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:gravity="center_vertical"         android:singleLine="true"         android:textAppearance="?android:attr/textAppearanceMedium"/> 

  • 确保你的视图组件对于坐在屏幕前10英寸(这个距离对于更大的屏幕会更大)远的用户,足够大至清晰可见。这样做的最好方式是使用相对布局大小而不是绝对大小,并且使用基于密度的像素单位替代绝对像素单位。例如,为了设置一个控件的宽度,使用wrap_content替代像素尺寸,并且设置控件的边距,使用dip替代像素值。 

 

针对高密度大屏幕设计 

———————————————————————————————————————

常见的HDTV显示分辨率是720p,1080i和1080p。针对1080p设计你的UI,然后如果又必要的话,允许Android系统缩放你的UI适应720p。通常,缩减(移除像素)不会降低UI(注意到反过来是不正确的;你需要避免放大,应为它降低UI的质量)。 

 

为了获取图片最好的缩放结果,如果可能以9-patch提供图片。如果你在你的布局中使用低质量的图片或者小图片,它们将出现模糊或者颗粒状。这对于用户来说是不好的体验。使用高质量的图片替代。 

 

更新关于针对大屏幕优化应用的信息,查阅Designing for multiple screens。 

 

设计处理较大的位图 

———————————————————————————————————————

Android系统有内存大小的限制,所以在你的应用中下载和存储高分辨率的图片,会经常导致内存溢出错误。为了避免这个,遵循下面的这些提示: 

  • 仅仅在当它们被显示的时候加载图片。例如,当在一个GridView或者Gallery中显示多张图片的时候,当在视图的Adatper中的getView()被调用的时候仅仅加载一张图片。 

  • 在不在使用的Bitmap视图上调用recyle()。 

  • 在一个内存集合中使用WeakReference存储Bitmap对象的引用。 

  • 如果从网络获取图片,使用AsyncTack获取它们,并且在SD卡上保存它们用于快速访问。不要在应用程序的UI线程中进行网络传输。 

  • 当你下载它们的时候,缩小很大的图片到一个合适的大小;另一方面,下载图片本身可能导致“内存溢出”异常。下面的例子当下载的时候缩小图片: 

// Get the source image's dimensions   BitmapFactory.Options options = new BitmapFactory.Options();   // This does not download the actual image, just downloads headers.   options.inJustDecodeBounds = true;    BitmapFactory.decodeFile(IMAGE_FILE_URL, options);   // The actual width of the image.   int srcWidth = options.outWidth;     // The actual height of the image.   int srcHeight = options.outHeight;      // Only scale if the source is bigger than the width of the destination view.   if(desiredWidth > srcWidth)     desiredWidth = srcWidth;    // Calculate the correct inSampleSize/scale value. This helps reduce memory use. It should be a power of 2.   int inSampleSize = 1;   while(srcWidth / 2 > desiredWidth){     srcWidth /= 2;     srcHeight /= 2;     inSampleSize *= 2;   }    float desiredScale = (float) desiredWidth / srcWidth;    // Decode with inSampleSize   options.inJustDecodeBounds = false;   options.inDither = false;   options.inSampleSize = inSampleSize;   options.inScaled = false;   // Ensures the image stays as a 32-bit ARGB_8888 image.   // This preserves image quality.   options.inPreferredConfig = Bitmap.Config.ARGB_8888;                                                              Bitmap sampledSrcBitmap = BitmapFactory.decodeFile(IMAGE_FILE_URL, options);    // Resize   Matrix matrix = new Matrix();   matrix.postScale(desiredScale, desiredScale);   Bitmap scaledBitmap = Bitmap.createBitmap(sampledSrcBitmap, 0, 0,       sampledSrcBitmap.getWidth(), sampledSrcBitmap.getHeight(), matrix, true);   sampledSrcBitmap = null;    // Save   FileOutputStream out = new FileOutputStream(LOCAL_PATH_TO_STORE_IMAGE);   scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);   scaledBitmap = null;