• Blog
  • OPhone UI开发者指南

OPhone UI开发者指南

UI设计, 2009-08-27 16:30:28

Tags : UI OPhone 李若飞

1、多分辨率设备支持

        随着OPhone平台的问世,越来越多的个人和企业开发者都将更多的目光投向了这个基于开放移动系统的智能手机平台。OPhone应用开发社区也在不断壮大。但我们发现,OPhone应用开发常常会遇到多分辨率支持的问题。OPhone平台对这个问题提供了一个很好的解决方案。以下将通过详细的实例来向大家介绍这一解决方案。(作者:李若飞)

1.1 HVGA(480x320)分辨率支持实例

1.1.1创建一个新的工程

        命名为diffResolutioin,工程结构如下图所示:

1.1.2 创建两个Activity

        同时需要创建两个类,第一个命名为diffResolution.java,源代码如下:

 

package com.test.diffResolution;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; 

public class diffResolution extends Activity implements OnClickListener{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView ResultText = (TextView)findViewById(R.id.ResultText);
        ResultText.setText("The app is created for the different image resolution test!");
        Button ResolutionTest = (Button)findViewById(R.id.ResolutionTest);
        ResolutionTest.setOnClickListener(this);
    }

	public void onClick(View arg0) {
		if (arg0.getId() == R.id.ResolutionTest) {
			startTest();
			}
	}
	
	private void startTest() {
		//Start another Activity by Intent
		Intent intent = new Intent (diffResolution.this, startTest.class);
		startActivity(intent);
	}
}

        另一个命名为startTest.java,源代码如下:

 

package com.test.diffResolution;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;

public class startTest extends Activity{
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.start_test);
    }
}

 

1.1.3 用户界面布局文件

 

        需要对每个Activity编辑页面布局文件:main.xml和start_test.xml。main.xml源代码如下:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
    android:layout_height="wrap_content" 
    android:layout_width="fill_parent" 
    android:layout_below="@+id/ExitButton" 
    android:id="@+id/ResultText"></TextView>
<Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content"  
    android:id="@+id/ResolutionTest" 
    android:layout_below="@+id/BaseEdit" 
    android:text="Press to begin Test" ></Button>
</LinearLayout>

        start_test.xml 源代码如下:

 

<?xml version="1.0" encoding="utf-8"?>
	  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/base_layout"
    android:layout_width="320px"
    android:layout_height="480px"
    android:orientation="vertical"
    android:background="@drawable/testpic"> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="80dip"
    android:layout_alignParentTop="true"
    android:layout_marginTop="60dip"
    android:background="@drawable/title_text"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="80dip"
    android:layout_alignParentTop="true"
    android:layout_marginTop="150dip"
    android:background="@drawable/chess"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="30dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="25dip"
    android:background="@drawable/start1"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="45dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="75dip"
    android:background="@drawable/start2"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_marginLeft="30dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="25dip"
    android:background="@drawable/close1"/> 
  
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_marginLeft="40dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="78dip"
    android:background="@drawable/close2"/> 
</RelativeLayout>

 

1.1.4 运行程序

        直接运行,得到如下应用界面:

     

 

1.2 多分辨率设备兼容性问题

        可以看到,测试页面的用户界面布局清晰合理。但当把同一应用安装在分辨率为nHD(640x360)的设备上,用户界面还会是这样么?

    

 

        由于分辨率的不同,导致用户界面的图片布局出现了比较严重的偏离。如何避免这一问题,OPhone平台提供了同一应用适应不同分辨率设备的解决方案。

1.3 多分辨率设备兼容性问题解决方案

1.3.1 基本思路

  1. 首先应当明确应用希望支持几种分辨率设备;
  2. 其次,需明确哪些资源文件在不同分辨率的设备存在显示问题;
  3. 对于显示有问题的,需要重新准备与相应分辨率设备适配的资源文件和页面布局文件。

        下面我们就上面的例子来修改使之适配不同的分辨率。当前例子的适配分辨率是480x320,我们希望通过修改,能使其适配nHD(640x360)的分辨率。

1.3.2工程目录更新

        在res目录下创建两个新的文件夹,分别命名为drawable-640x360和layout-640x360。这里需要注意的是,较大的值应该放在前面。然后将适配当前分辨率的图片文件加载到drawable-640x360,同时保证这里加载的图片名称应该和drawable目录下的对应的图片名称一致。图片加载完成后,就需要依据当前的分辨率创建新的页面布局文件,布局文件存放在layout-640x360文件夹里。同样,这里的页面布局文件名称也应该和layout目录下相应的布局文件名称一致。

1.3.3 页面布局文件调整

        接下来,就可以按照相应的分辨率来对我们的应用进行调试,对layout-640x360目录下的页面布局进行调整,使之适配分辨率为nHD(640x360)的设备。start_test.xml源代码为:

 

<?xml version="1.0" encoding="utf-8"?>
	  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/base_layout"
    android:layout_width="360px"
    android:layout_height="570px"
    android:orientation="vertical"
    android:background="@drawable/testpic"> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="90dip"
    android:layout_alignParentTop="true"
    android:layout_marginTop="70dip"
    android:background="@drawable/title_text"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="90dip"
    android:layout_alignParentTop="true"
    android:layout_marginTop="180dip"
    android:background="@drawable/chess"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="30dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="25dip"
    android:background="@drawable/start1"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginRight="45dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="75dip"
    android:background="@drawable/start2"/> 
    
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_marginLeft="30dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="25dip"
    android:background="@drawable/close1"/> 
  
    <RelativeLayout 
    android:id="@+id/test_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_marginLeft="40dip"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="78dip"
    android:background="@drawable/close2"/> 
</RelativeLayout>

        对比drawable文件夹下的starttest.xml文件和drawable-640x360文件夹下的starttest.xml,我们发现,二者的区别就是对图片资源文件testpic.png, title_text.png和chess.png的页面布局调整。

1.3.4 运行程序

        现在,分别在分辨率为HVGA(480x320)和nHD(640x360)的设备上运行我们的测试程序。

        在分辨率为HVGA(480x320)设备上的运行结果:

   

        在分辨率为nHD(640x360)设备上的运行结果:

   

        可以看到应用非常完美的展现在你的面前。

        如果想要支持更多的分辨率设备,也只需要创建相应分辨率的资源文件夹和页面布局文件夹,同时将修改后的资源文件的页面布局文件存放在里面。OPhone系统在编译运行时会根据当前设备分辨率,自动选择相应的资源文件和页面布局文件。

2. 其他需要注意的UI问题

2.1.1 title bar和Status bar问题

        OPhone平台中,title bar有三个作用:Home屏按键、应用名称显示、后退按键。对于某些产品而言,有专门的Home屏按键和后退按键。而有些应用却需要全屏显示。这就需要开发人员去判断是否需要隐藏title bar和status bar。默认情况下,二者是显示的。如果需要隐藏,则需要在当前Activity的Java源文件引入android.view.Window和android.view.WindowManager,并在oncreate()方法中调用:

 

//Hide title bar;
requestWindowFeature(Window.FEATURE_NO_TITLE);
//Hide status bar;
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        注意,该方法需要在setContentView(R.layout.start_test)之前调用,否则会出现force close 错误。

2.1.2 页面布局方法的选择

        对于一些简单的应用界面,如果对图片的显示没有特别精确的要求,可以通过相对布局RelativeLayout的方法去定义。背景图片可以直接应用wrap_content。它的优点是无论何种分辨率的设备都可以全屏显示,但缺点也很明显,就是或多或少图片都需要拉伸,从而会造成图像变形。所以,我们说,只有在对图片显示要求不是很严格的情况下,可以使用这种方法。

 

	android:id="@+id/base_layout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
	android:background="@drawable/testpic">

         实例中由于背景图片是单一颜色,所以使用fill_content这种方法不会造成图像变形。运行结果如下:

   

2.1.3 慎用AbsoluteLayout

        最后,还要强调的是,不要使用AbsoluteLayout。使用这种方法会大大降低应用的兼容性。而且会使将来的维护成本增大。

(声明:本网的新闻及文章版权均属OPhone SDN网站所有,如需转载请与我们编辑团队联系。任何媒体、网站或个人未经本网书面协议授权,不得进行任何形式的转载。已经取得本网协议授权的媒体、网站,在转载使用时请注明稿件来源。)