1. 程式人生 > >bootstrap之Orientation

bootstrap之Orientation

sys mes sage nds dha param ack bject left

Orientation


調整屏幕方向的操作。


package io.appium.android.bootstrap.handler;

import android.os.RemoteException;
import com.android.uiautomator.core.UiDevice;
import io.appium.android.bootstrap.*;
import org.json.JSONException;

import java.util.Hashtable;

/**
 * This handler is used to get or set the orientation of the device.
 * 
 */
public class Orientation extends CommandHandler {

  /*
   * @param command The [email protected]
/* */ AndroidCommand} used for this handler. * * @return [email protected] AndroidCommandResult} * * @throws JSONException * * @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android. * bootstrap.AndroidCommand) */ @Override public AndroidCommandResult execute(final AndroidCommand command) throws JSONException { final Hashtable<String, Object> params = command.params(); if (params.containsKey("orientation")) { // Set the rotation final String orientation = (String) params.get("orientation"); try { return handleRotation(orientation); } catch (final Exception e) { return getErrorResult("Unable to rotate screen: " + e.getMessage()); } } else { // Get the rotation return getRotation(); } } /** * Returns the current rotation * * @return [email protected]
/* */ AndroidCommandResult} */ private AndroidCommandResult getRotation() { String res = null; final UiDevice d = UiDevice.getInstance(); final OrientationEnum currentRotation = OrientationEnum.fromInteger(d .getDisplayRotation()); Logger.debug("Current rotation: " + currentRotation); switch (currentRotation) { case ROTATION_0: case ROTATION_180: res = "PORTRAIT"; break; case ROTATION_90: case ROTATION_270: res = "LANDSCAPE"; break; } if (res != null) { return getSuccessResult(res); } else { return getErrorResult("Get orientation did not complete successfully"); } } /** * Set the desired rotation * * @param orientation * The rotation desired (LANDSCAPE or PORTRAIT) * @return [email protected]
/* */ AndroidCommandResult} * @throws RemoteException * @throws InterruptedException */ private AndroidCommandResult handleRotation(final String orientation) throws RemoteException, InterruptedException { final UiDevice d = UiDevice.getInstance(); OrientationEnum desired; OrientationEnum current = OrientationEnum.fromInteger(d .getDisplayRotation()); Logger.debug("Desired orientation: " + orientation); Logger.debug("Current rotation: " + current); if (orientation.equalsIgnoreCase("LANDSCAPE")) { switch (current) { case ROTATION_0: d.setOrientationRight(); desired = OrientationEnum.ROTATION_270; break; case ROTATION_180: d.setOrientationLeft(); desired = OrientationEnum.ROTATION_270; break; default: return getSuccessResult("Already in landscape mode."); } } else { switch (current) { case ROTATION_90: case ROTATION_270: d.setOrientationNatural(); desired = OrientationEnum.ROTATION_0; break; default: return getSuccessResult("Already in portrait mode."); } } current = OrientationEnum.fromInteger(d.getDisplayRotation()); // If the orientation has not changed, // busy wait until the TIMEOUT has expired final int TIMEOUT = 2000; final long then = System.currentTimeMillis(); long now = then; while (current != desired && now - then < TIMEOUT) { Thread.sleep(100); now = System.currentTimeMillis(); current = OrientationEnum.fromInteger(d.getDisplayRotation()); } if (current != desired) { return getErrorResult("Set the orientation, but app refused to rotate."); } return getSuccessResult("Rotation (" + orientation + ") successful."); } }

這個事件有點小復雜哈,當初研究uiautomator源代碼時就被它折騰的不行。也僅僅實驗了左和上的方向成功。

沒辦法,既然又遇到了,那就僅僅能純理論講啦。


execute方法中。首先推斷參數中是否含有orientation,假設含有調用handleRotation。否則調用getRotation。


所以execute又分流到上面的2個方法中。


handleRotation


這樣的情況是參數裏含有orientation,此時。我們來看看該方法中做了哪些事。


final UiDevice d = UiDevice.getInstance();
    OrientationEnum desired;
    OrientationEnum current = OrientationEnum.fromInteger(d
        .getDisplayRotation());


首先獲取當前設備的方向,然後初始化一個私有變量,以備後用。當中OrientationEnum枚舉類裏定義了4個方向,fromInteger方法是依據整數值得到對應的枚舉值,當中各個值的意思。


public enum OrientationEnum {
  ROTATION_0(0), ROTATION_90(1), ROTATION_180(2), ROTATION_270(3);

  public static OrientationEnum fromInteger(final int x) {
    switch (x) {
      case 0:
        return ROTATION_0;
      case 1:
        return ROTATION_90;
      case 2:
        return ROTATION_180;
      case 3:
        return ROTATION_270;
    }
    return null;
  }


ROTATION_0:你正常查看手機時,豎屏。此時屏幕的方向為0度。此時的power鍵在頂端。

例如以下:

技術分享


ROTATION_90:你將上面的屏幕向右順時針旋轉90度,此時設備旋轉角度為90度,此時我的power鍵在右端。假設此時你的設備能夠自己主動旋轉屏幕的話。你屏幕裏面的內容應該是什麽樣的?例如以下所看到的


技術分享


ROTATION_180:從90度角再向下順時針旋轉90度。此時我的power鍵在下端。此時的角度為180.因為我的手機禁止了這樣的自由旋轉,所以此時的屏幕展如今我的面前是這樣一番景象:


技術分享


ROTATION_270:從180度再順時針想左旋轉90度。此時我power鍵在左邊。此時為270度。展如今我面前的圖例如以下:


技術分享


假設你理解了上面4個keyword的意思。那麽以下理解代碼就非常easy啦。


handleRotation方法裏做完初始化操作以後。就要推斷client要求是橫屏還是豎屏。假設是橫屏,處理例如以下:


if (orientation.equalsIgnoreCase("LANDSCAPE")) {
      switch (current) {
        case ROTATION_0:
          d.setOrientationRight();
          desired = OrientationEnum.ROTATION_270;
          break;
        case ROTATION_180:
          d.setOrientationLeft();
          desired = OrientationEnum.ROTATION_270;
          break;
        default:
          return getSuccessResult("Already in landscape mode.");
      }
    }

假設是橫屏的話,那麽僅僅須要處理屏幕處於0度和180度的情況,由於90度和270度都已經是橫屏啦,自然不須要再處理。


假設是ROTATION_0,說明設備朝上,此時想要橫屏,自然是順時針向右旋轉一下屏幕。此時,正常情況下能夠旋轉的話。屏幕裏的視圖應該是從左到右的,所以desired的值才會被設置為ROTATION_270.所以要分清屏幕的角度和視圖的角度。

以下就是向右順時針旋轉90度後,裏面的視圖是270度的。此時power鍵在右端。

技術分享


假設是ROTATION_180度,說明設備拿反了,power鍵朝下。此時你向左順時針旋轉90度或者向右逆時針旋轉90度。都能達到橫屏的效果。源代碼裏是向左旋轉的,此時power鍵朝左,視圖和上面是一樣的,desired的值為ROTATION——270.


====================================================================================================================================


假設client傳遞過來的命令想要的是豎屏。就要走else裏的代碼塊:


else {
      switch (current) {
        case ROTATION_90:
        case ROTATION_270:
          d.setOrientationNatural();
          desired = OrientationEnum.ROTATION_0;
          break;
        default:
          return getSuccessResult("Already in portrait mode.");
      }
    }

此時僅僅要處理90度和270的情況。我們要把它變為ROTATION_0的情況,d.setOrientationNatural()是設置設備轉到自然方向,該方向就是設備初始設置的方向。說明通常的設備橫屏的2個方向能夠旋轉。豎屏方向就僅僅有一個方向能夠旋轉。上面的處理完成後,方法會做一個推斷,推斷是否旋轉成功。


 current = OrientationEnum.fromInteger(d.getDisplayRotation());
    // If the orientation has not changed,
    // busy wait until the TIMEOUT has expired
    final int TIMEOUT = 2000;
    final long then = System.currentTimeMillis();
    long now = then;
    while (current != desired && now - then < TIMEOUT) {
      Thread.sleep(100);
      now = System.currentTimeMillis();
      current = OrientationEnum.fromInteger(d.getDisplayRotation());
    }
    if (current != desired) {
      return getErrorResult("Set the orientation, but app refused to rotate.");
    }
    return getSuccessResult("Rotation (" + orientation + ") successful.");

首先獲得此時屏幕的方向,然後推斷一下與預期的是否同樣。假設不同樣,等待2秒鐘,再獲取一次屏幕的方向,假設經過這麽一次驗證完成後。當前的屏幕方向仍然和預期的不同樣,那麽就返回旋轉失敗的消息給client。假設同樣的話,就返回旋轉成功的消息給client。


到此為止handleRotation處理完成。以下處理參數裏不含有orientation的情況。


getRotation


該方法中就是依據當前的屏幕的方向得到橫屏還是豎屏,將結果返回給client。

非常easy。



總結


通過上面的分析。說明client關於屏幕方向的命令有2種:


大家要特別主要選擇方向的定義,設備的方向和裏面視圖的方向的差別。






bootstrap之Orientation

相關推薦

bootstrapOrientation

sys mes sage nds dha param ack bject left Orientation 調整屏幕方向的操作。 package io.appium.android.bootstrap.handler; import and

bootstrapdaterangepicker---漢化以及擴展

組件 tro div time 事件 r.js 日期 功能 date 一、擴展的功能 1、初始化時,會自動創建一個select標簽; 2、當改變select值時,日期也會自動改變,並且會調用apply按鈕的click事件 3、點擊此處進行

重修課程day54(bootstrapcss樣式)

mit tip erro context ups highlight tac esc boot 一 bootstrap的介紹  Bootstrap是將html,css和js的代碼打包好了,只管我們拿來調用。是基於jquery開發的。  使用BootCDN提供的免費CDN加速

重修課程day55(BootstrapBootstrap組件)

warn other thumbnail 選擇 膠囊 inverse con port nav-tab 一 文本居中  col-xx-offset-xx:水平居中  center-block:使用於不涉及float標簽的水平居中,也不涉及列的居中,讓哪裏居中就寫到哪裏,本質

bootstrapCSS全局樣式

ins 定義 添加 文本 必須 pad 多個 子類 內容 一、排版樣式(paiban)   1、標題標簽   <body style="padding:20px">   <h1>h1.bootstrap</h1><br/>

Bootstrapjavascript插件---彈出框(模態框)Modal

boot mis out strong 設置 cnblogs true -o 分享圖片 簡介:   彈出框是一個經常使用的組件,一般用於彈出提示信息,確認信息,表單內容。 完整結構分析(可以沒有頭部和底部): 代碼示例: <!-- 彈出框的頭部 -->

ssm整合bootstrap分頁

java ssm pageHelper 分頁 bootstrap 分頁是我們經常會碰到的需求之一,今天我們就使用企業中很常用的mybatis分頁插件pageHelper來給大家做一個ssm整合bootstrap分頁的案例先看效果圖:一:建立數據庫student:學生表student年級表g

bootstrapdata-*常用屬性

ogg bpa -c div AS oot model ref role 【1】data-toggle:指以什麽事件類型觸發,常用的有 data-toggle="button" //按鈕事件 data-toggle="dropdown" //下拉菜單 da

bootstrap增刪改查

ali odata .html 顯示 return style pagelist CA null 後臺使用spring boot和spring cloud等。前端使用bootstrap框架進行基本操作,項目采用前後端分離。 1、查詢 <!-- HTML中代碼 此中

Bootstrap底層媒體查詢

ner isp width box 20px direct gree child cti <style> @media only screen and (min-width:1024px ) { #box{ display: fl

Bootstrap柵格系統

1、柵格系統(佈局) Bootstrap內建了一套響應式、移動裝置優先的流式柵格系統,隨著螢幕裝置或視口(viewport)尺寸的增加,系統會自動分為最多12列。 我在這裡是把Bootstrap中的柵格系統叫做佈局。它就是通過一系列的行(row)與列(column)的組合建立頁面佈局,然後你的內

Bootstrapfileinput檔案上傳控制元件

 前言~ 前段時間做專案用到了bootstrap裡中的檔案上傳控制元件,對此特定寫這篇文章,講述一下bootstrap的檔案上傳空間的使用方法。 我們進入正題吧!        首先bootstrap是基於jquery的,因此要匯入

Bootstrap初始Bootstrap個人總結

1、什麼是Bootstrap? Bootstrap是由Twiter的Mark Otto和Jacob ThornTon 兩位設計師開發的。 Bootstrap是2011年8月在GitHub上釋出的開源產品(開發原始碼)。 Bootstrap是個用於快速開發Web應用程式和網站的前端

bootstrapdatetimepicker的使用

1、引入檔案         除了引入基本的jquery和bootstrap的js、bootstrap的css外,還需要引入bootstrap-datetimepicker.min.js,還有就是bootstrap-datet

bootstrap 表單佈局

文章來自:原始碼線上https://www.shengli.me/css/422.html   垂直表單:     效果圖:       (2)內聯表單:它的所有元素是內聯的,向左對齊的,標籤

BootStrap包涵下拉選單的輸入框

用法: <div class="row col-md-5 text-center"> <div class="input-group"><!--保持內聯,消除邊框,類

BootStrapnavigation導航

普通導航: <ul class="nav nav-tabs nav-justified"> <!-- class=“active”:表示選中當前tab頁,高亮顯示,通過

BootStrap面板panel

普通面板: <div class="col-md-6"> <div class="panel panel-default"> <div class="pane

BootStrap彈窗alert

資訊彈窗: <div class="row"> <div class="col-md-4"> <div class="alert alert-info">資訊

Angular6+ngx-bootstrap模態框的使用(三)

方法一: app.module.ts import {ModalModule} from 'ngx-bootstrap/modal'; ModalModule.forRoot() app.component.html <button class="btn btn-o