现在的位置: 首页 > 综合 > 正文

Android–屏幕方向的改变

2014年09月05日 ⁄ 综合 ⁄ 共 6159字 ⁄ 字号 评论关闭

        如果设备的配置(在 Resources.Configuration 中进行了定义)发生改变,那么所有用户界面上的东西都需要进行更新,以适应新的配置。因为 Activity 是与用户交互的最主要的机制,它包含了处理配置改变的专门支持。除非你特殊指定,否则当配置发生改变(比如屏幕方向、语言、输入设备等等的改变)时你当前的 activity 都将被销毁,这销毁是通过一个正常的activity 生命周期过程( onFreeze(Bundle)
, onPause() , onStop() , 
 onDestroy() )进行的。如果 activity 之前正在前景画面,当这个实例的 onDestroy() 调用完成后将会启动这个 activity 的一个新的实例,并将前面那个实例中 onFreeze(Bundle) 所保存的内容传递给新的实例。因为任何的应用资源(包括 layout 文件)都有可能由于任何配置值而改变。因此处理配置改变的唯一安全的方法就是重新获取所有的资源,包括 layout 、绘图资源(原文 drawables )、字符串资源。由于 activity 已经如何保存自己的状态并从这些状态中重建自身,所以 activity 重新启动自身来获得新的配置将是一个非常便利的途径。在一些特殊的情况中,你可能希望当一种或者多种配置改变时避免重新启动你的 activity 。你可以通过在manifest中设置android:configChanges 属性来实现这点。你可以在这里声明 activity 可以处理的任何配置改变,当这些配置改变时不会重新启动 activity ,而会调用 activity  onConfigurationChanged(Resources.Configuration) 方法。如果改变的配置中包含了你所无法处理的配置(在 android:configChanges 并未声明),你的 activity 仍然要被重新启动,而onConfigurationChanged(Resources.Configuration) 将不会被调用。


下面给出两个例子说明屏幕的改变事件。

1.点击按钮改变屏幕的方向

实现的截图如下:


实现这个例子用到的代码如下:

public class EX05_22 extends Activity
{
  private TextView mTextView01;
  private Button mButton01;
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    /* 方法又需要用到的Display对象 */
    final Display defaultDisplay = getWindow().getWindowManager().getDefaultDisplay();
    
    mButton01 = (Button)findViewById(R.id.myButton1); 
    mTextView01 = (TextView)findViewById(R.id.myTextView1);
    
    if(getRequestedOrientation()==-1)
    {
      mTextView01.setText(getResources().getText(R.string.str_err_1001));
    }
    
    /* 当按下按钮旋转屏幕画面 */
    mButton01.setOnClickListener(new Button.OnClickListener()
    {
      @Override
      public void onClick(View arg0)
      {
        /* 方法一:重写getRequestedOrientation */
        
        /* 若无法取得screenOrientation属性 */
        if(getRequestedOrientation()==-1)
        {
          /* 提示无法进行画面旋转叫能,帆无法??Orientation */
          mTextView01.setText(getResources().getText(R.string.str_err_1001));
        }
        else
        {
          if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
          {
            /* 若当前为横式,则变更为直式显示 */
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
          }
          else if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
          {
            /* 若当前为直式,则变更为横式显示 */
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
          }
        }
        
        /* 方法二:判断屏幕宽高比(扩展学习) */
        int h= defaultDisplay.getHeight();
        int w = defaultDisplay.getWidth();
        
        /* 否分辨率为按钮按下当下的分辨率 */
        mTextView01.setText(Integer.toString(h)+"x"+Integer.toString(w));
        
        //if(w > h)
        //{
          /* Landscape */
          /* 重写Activity里的setRequestedOrientation()方法 */
        //  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        //}
        //else
        //{
          /* Portrait */
        //  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        //}
      }      
    });
  }

  @Override
  public void setRequestedOrientation(int requestedOrientation)
  {
    // TODO Auto-generated method stub
    
    /* 判断要变更的方向,以Toast提示 */
    switch(requestedOrientation)
    {
      case (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE):
        mMakeTextToast
        (
          getResources().getText(R.string.str_msg1).toString(),
          false
        );
        break;
      case (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT):
        mMakeTextToast
        (
          getResources().getText(R.string.str_msg2).toString(),
          false
        );
        break;
    }
    super.setRequestedOrientation(requestedOrientation);
  }

  @Override
  public int getRequestedOrientation()
  {
    // TODO Auto-generated method stub
    
    /* 此重写getRequestedOrientation方法,可取得当前屏幕的方向 */
    return super.getRequestedOrientation();
  }
  
  public void mMakeTextToast(String str, boolean isLong)
  {
    if(isLong==true)
    {
      Toast.makeText(EX05_22.this, str, Toast.LENGTH_LONG).show();
    }
    else
    {
      Toast.makeText(EX05_22.this, str, Toast.LENGTH_SHORT).show();
    }
  }
}


2.动态改变屏幕的方向,并重载函数

 public void onConfigurationChanged(Configuration newConfig)

这时需要两个权限的说明

2.1

<!-- 必須設定CHANGE CONFIGURATION權限 -->
  <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission>


2.2

 <!-- 必須設定activity的configChanges屬性 -->
    <activity
      android:name=".EX05_23"
      android:label="@string/app_name"
      android:configChanges="orientation|keyboard">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

实现的效果与第一个例子相同。

下面给出完整的实现代码:

public class EX05_23 extends Activity
{
  private TextView mTextView01;
  private Button mButton01;
  
  /* 屏幕宽高 */
  private int intScreenH,intScreenW;
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    /* 声明Display对象,以取得屏幕宽高 */
    final Display defaultDisplay = getWindow().getWindowManager().getDefaultDisplay();
    intScreenH= defaultDisplay.getHeight();
    intScreenW = defaultDisplay.getWidth();
    
    mButton01 = (Button)findViewById(R.id.myButton1); 
    mTextView01 = (TextView)findViewById(R.id.myTextView1);
    mTextView01.setText(Integer.toString(intScreenW)+"x"+Integer.toString(intScreenH));
    
    /* 当宽>高,表示为横式显示 */
    if(intScreenW > intScreenH)
    {
      /* Landscape */
      mButton01.setText(R.string.str_button2);
    }
    else
    {
      /* Portrait */
      mButton01.setText(R.string.str_button1);
    }
    
    /* 按钮事件处理切换宽高 */
    mButton01.setOnClickListener(new Button.OnClickListener()
    {
      @Override
      public void onClick(View v)
      {
        // TODO Auto-generated method stub
        intScreenH= defaultDisplay.getHeight();
        intScreenW = defaultDisplay.getWidth();
        
        /* 如果为Landscape */
        if(intScreenW > intScreenH)
        {
          /* Landscape => Portrait */
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        else
        {
          /* Portrait => Landscape */
          setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
        
        /* 再一次取得屏幕宽高 */
        intScreenH= defaultDisplay.getHeight();
        intScreenW = defaultDisplay.getWidth();
        mTextView01.setText(Integer.toString(intScreenW)+"x"+Integer.toString(intScreenH));
      }
    });
  }  
  
  @Override
  public void onConfigurationChanged(Configuration newConfig)
  {
    // TODO Auto-generated method stub
    
    /* 覆写onConfigurationChanged事件,捕捉当设定之后的值 */
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
    {
      /* 趁着事件发生之后,变更按钮上的文字 */
      mButton01.setText(R.string.str_button2);
      mMakeTextToast
      (
        getResources().getText(R.string.str_onConf_LANDSCAPE).toString(),
        false
      );
    }
    
    /* 须设定configChanges属性才能捕捉onConfigurationChanged */
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
    {
      mButton01.setText(R.string.str_button1);
      mMakeTextToast
      (
        getResources().getText(R.string.str_onConf_PORTRAIT).toString(),
        false
      );
    }
    
    if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO)
    {
     
    }
    super.onConfigurationChanged(newConfig);
  }
  
  public void mMakeTextToast(String str, boolean isLong)
  {
    if(isLong==true)
    {
      Toast.makeText(EX05_23.this, str, Toast.LENGTH_LONG).show();
    }
    else
    {
      Toast.makeText(EX05_23.this, str, Toast.LENGTH_SHORT).show();
    }
  }
}

抱歉!评论已关闭.