UWP開發砸手機系列(一)—— Accessibility


  因為今天討論的內容不屬於入門系列,所以我把標題都改了。這個啥Accessibility說實話屬於及其蛋疼的內容,即如何讓視力有障礙的人也能通過聲音來使用觸屏手機……也許你這輩子也不會接觸,但如果有一天你遇到了,碰巧你又看了我這一篇,你就可以挺起胸膛大聲說:這個逼我裝定了!

  首先我們來看下AccessibilityWindows 10 Mobile上原生支持的情況,點擊“設置”-》“輕松使用”-》“講述人”,開啟講述人之后,你可以先體驗個幾分鍾(另外講述人對中文的支持並不是很好,建議切換到英文系統)。

  我知道你想砸手機,但先別急着,等我們把今天的內容講完再砸……

  如何實現讓“講述人”朗讀屏幕內容呢?按照某軟一貫的尿性,HelloWorld必然簡單到讓人發指,只需給想要被朗讀的控件添加“AutomationProperties.Name”就可以了。

        <Button AutomationProperties.Name="I am a button">Button</Button>

  手指戳上去的時候就會聽到“I am a button”。如果你做完了這個Sample然后就跑去匯報可行性,那你就完了……

  首先我們遇到的第一個問題就是講述人無法識別自定義的控件,甚至連GridBorder這樣的默認沒有交互的控件也不會識別,這個是很糟糕的。項目中難免會用到一些UserControlCustomControl的,DataTemplate里又總會用到Grid啥的。這里統統讀不出來,作為一個負責任的大公司,產品就不能發布了,后果很嚴重。

  如何解決這個問題呢?其實也沒那么復雜啦,某軟還是提供了一些接口來做這些事情,參考了MSDN上的文檔(極其沒有卵用)和給出的Sample(有誤導人的嫌疑),最終又查看了SilverlightButtonTextBlock的源碼(Windows Runtime貌似沒有可以反編譯的工具可以看到源碼,ILSpyJustDecompile均只能看到接口定義)。給出以下的解決方案:

  解決方案以Grid舉例,意圖讓“講述人”識別Grid並念出AutomationProperties.Name中填寫的文本。

    public class CanReadGrid : Grid
    {
        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new GridAutomationPeer();
        }
    }

    public class GridAutomationPeer : AutomationPeer
    {
        protected override object GetPatternCore(PatternInterface patternInterface)
        {
            if (patternInterface == PatternInterface.Grid)
            {
                return this;
            }

            return null;
        }

        protected override AutomationControlType GetAutomationControlTypeCore()
        {
            return AutomationControlType.Custom;
        }

        protected override string GetClassNameCore()
        {
            return "CanReadGrid";
        }
    }

  第一步需要繼承自現有的系統控件Gird,然后override方法OnCreateAutomationPeer,該方法繼承自UIElement,已經是非常底層的對象了。但如果你去查看Grid類本身的接口定義,會發現Grid是沒有對該方法做處理的。而默認就可以讀出的ButtonTextBlock等控件均override了該方法。

        //
        // Summary:
        //     在派生類中實現時,為 Microsoft UI 自動化基礎結構返回類特定的 AutomationPeer 實現。
        //
        // Returns:
        //     要返回的類特定的 AutomationPeer 子類。
        protected virtual AutomationPeer OnCreateAutomationPeer();

  第二步需要創建類GridAutomationPeer繼承自AutomationPeerAutomationPeer文檔中給出的說法是提供一個對 Microsoft
UI 自動化公開關聯所有者類的自動化同級的基類”。(雖然高考語文還可以,但仍不足以正確閱讀理解MSDN天書……)既然文檔看不懂,干脆就直接抄襲ButtonTextBlock的源碼來寫唄。經反復比較推敲,確認了最為核心的方法protected override object GetPatternCore(PatternInterface
patternInterface),親測鑒定只要實現了該方法,即可由講述人識別。GetAutomationControlTypeCoreGetClassNameCore都只是錦上添花而已。最終使用的XAML如下:

    <local:CanReadGrid Background="Red"
                       AutomationProperties.Name="Can read gird">
    </local:CanReadGrid>

  這個自定義的Grid終於能被“講述人”毫無感情的念出“can read gird”了。說實話還是Contana的聲音好聽一些。

  本篇介紹了如何讓講述人念出自定義控件,並強力建議先不要砸手機或匯報可行性分析,因為我還留了一個大坑給你們。可交互的控件比如Button,講述人會語音提示雙擊可以激活Click操作,通過ViewModel中的Command綁定也沒有問題。但問題是沒有Command屬性的控件要如何處理?通過Behaviors綁定的Command是萬萬不可能會自動識別的啦?想要知道答案的,下個禮拜見……

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM