-UI調試工具 SAK 佈局 MD

Markdown版本筆記 個人GitHub首頁 個人博客 個人微信 個人郵箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目錄

SwissArmyKnife

SwissArmyKnife
autopilot 分支
效果視頻android

SwissArmyKnife 是一款方便調試android UI的工具。能夠直接在android設備屏幕上顯示控件的相關信息git

接入方式

compile 'com.wanjian:sak:2.0.2'

no opt 包github

compile 'com.wanjian:sak-nop:0.0.3'
//開啓
SAK.init(Application application, Config config)

//關閉
SAK.unInstall();

啓動app後會在屏幕右側看到一個 藍色靶心雙擊便可進入功能界面。shell

Tips:
當開啓新窗口時(包括新的Activity、彈出dialog、pop),須要手動點擊一次屏幕右側的 靶心 按鈕,以此激活當前窗口,否則當前窗口不會啓用 SwissArmyKnife!微信

自動初始化版本

自動初始化版本app

Autopilot 版基於com.wanjian:sak:xx.xx.xx,實現了自動初始化,只須要在gradle中引入依賴便可,不須要編寫額外的初始化代碼ide

接入方式工具

compile 'com.wanjian:sak-autopilot:2.0.1'

no opt 包佈局

compile 'com.wanjian:sak-nop:0.0.3'

開啓及關閉
在控制檯執行 adb shell am broadcast -a com.sak命令便可開啓及關閉

支持的功能

Tips:
編輯控件、相對距離、移動控件,這幾個功能相互衝突,請勿同時開啓

經常使用的功能

  • Activity、Fragment名稱:能夠看到當前Activity的類名,每個Fragment的類名。
  • 相對距離:依次長按兩個控件便可顯示兩個控件間的水平和豎直距離
  • 拾取控件:拖動圓環到要拾取的控件位置,能夠獲取控件id、類型、位置、背景色、寬高、邊距、字體大小顏色等信息
  • 取色器:會在屏幕顯示綠色圓環,能夠任意拖動,屏幕下方會顯示圓環中心的顏色值(圓環的顏色也會改變)
  • 水平直尺、豎直直尺:會在屏幕顯示水平直尺和豎直直尺,能夠任意拖動進行測量,直尺上有px和dp兩個值
  • 邊框:顯示全部View的邊界(相似開發者選項中的"顯示佈局邊界"功能)

其餘支持的功能

  • 編輯控件長按須要編輯的控件便可彈出編輯窗口,能夠修改內外邊距大小、寬高、背景色、字體顏色大小等
  • 移動控件長按控件便可拖動
  • Scalpel:解剖刀,會立體顯示view,能夠直觀的查看view的層級關係,拖動屏幕左側的按鈕能夠切換角度
  • 網格:顯示網格
  • 字體大小:顯示全部TextView的大小
  • 字體顏色:顯示全部TextView的顏色
  • 外邊距:顯示全部View的外邊距(Margin)的大小(會填充一個背景色)
  • 內邊距:顯示全部View的內邊距(Padding)的大小(會填充一個背景色)
  • 寬高:顯示全部View的寬高
  • 圖片寬高:顯示全部ImageView的寬高
  • 背景色:顯示全部設置background的控件的背景色的值
  • 自定義信息
  • View類型:顯示全部View的類型
  • 佈局樹:顯示佈局樹
  • 性能:能夠看到當前窗口view的繪製耗時、事件分發耗時、measure耗時、layout耗時、handler耗時等信息
    • 開啓後會自動禁用硬件加速,實際繪製時間可能要少一些
    • ListView會在事件分發時調用getView,因此ListView事件分發時間稍微長一些
    • RecyclerView會在view繪製時bindView,因此RecyclerView繪製時間會稍長一些

可配置項

可配置項

  • 層級區間:Fragment名稱、外邊距、內邊距、寬高、字體大小、字體顏色、背景色等功能下,能夠經過設置層級區間過濾掉部分view,避免數值相互覆蓋
  • 單位:距離默認單位是dp,能夠切換爲dp、sp、px單位
  • 裁剪繪製範圍:若內外邊距、寬高、字體顏色等信息不顯示,能夠關閉 裁剪繪製。開啓該功能能夠避免能夠滾動的控件滾動後致使的信息覆蓋問題。

原理

實現過程:

  • 監聽window的建立,從而拿到每個window的根view。
  • 拿到根view(必須是FrameLayout或RelativeLayout)後給根view添加RootContainerViewRootContainerView內部包含了藍色的靶心view。每一個window都有一個專用的RootContainerView
  • 建立各window共用的DashBoardViewDashBoardView是其餘各功能view的容器,好比開啓取色功能後會把TakeColorView加到DashBoardView中。
  • 雙擊當前窗口的靶心按鈕會在當前窗口激活 SwissArmyKnife,實際上是把共用的DashBoardView添加到了當前窗口的RootContainerView中。
  • 每個功能都是AbsLayer的子類,AbsLayer繼承自FrameLayout。噹噹前窗口的任何一個view須要繪製時都會調用AbsLayeronUiUpdate方法,能夠在該方法裏繪製相關信息,好比邊框,字體顏色等。

自定義功能

能夠經過 Config 對 SAK 進行配置或自定義功能。

public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Config config = new Config.Build(this)
            .viewFilter(getViewFilter())
            .addLayerView(getLayerView())
            .addSizeConverter(getSizeConverter())
            .build();
        SAK.init(this, config);
    }
    
    private ISizeConverter getSizeConverter() {
        return new ISizeConverter() {
            // 能夠添加自定義的SizeConverter,默認提供了Origin*、Px2Dp*,Px2Sp*
            @Override
            public String desc() {
                return "my converter";
            }
            
            @Override
            public Size convert(Context context, float length) {
                return Size.obtain().setLength(length / 2).setUnit("myU");
            }
            
            @Override
            public int recovery(Context context, float length) {
                return 0;
            }
        };
    }
    
    private AbsLayer getLayerView() {
        // 能夠添加自定義的view,自定義的view要繼承自AbsLayer或其子類,AbsLayer是FrameLayout的子類
        // 當激活SwissArmyKnife時會調用 onAttached(View rootView)方法,rootView是當前window的根view,好比Activity的根view DecorView。
        //當停用是會調用`onDetached`
        return new AbsLayer(this) {
            @Override
            public String description() {
                return null;
            }
            
            @Override
            public Drawable icon() {
                return null;
            }
        };
    }
    
    private ViewFilter getViewFilter() {
        return new ViewFilter() {
            @Override
            public boolean apply(View view) {
                // 這裏能夠決定要顯示哪一種view,好比只顯示ImageView子類和LinearLayout子類
                // 若想要顯示全部可見的view,直接返回 view.getVisibility()==View.VISIBLE 便可
                return view instanceof ImageView || view instanceof LinearLayout;
            }
        };
    }
}

2019-6-30

相關文章
相關標籤/搜索