2014-09-02 78 views
5

我正在尋找一種技術來確定Java Wear設備屏幕是圓形還是矩形。請注意,這不僅僅是佈局;我的代碼實際上需要知道它處理的是哪個形狀,因爲它們的處理方式不同。根據我在網上的代碼示例中看到的,兩種不同的方法應該是可能的 - 但我一直無法讓他們中的任何一個人工作。我會將它們包含在這裏以消除它們的運行,或者可能的故障排除(如果任何人都可以看到它們的問題)。請不要將我引薦給另一個SO職位,只是重申在這裏不適合我的解決方案。以編程方式確定Android Wear中的屏幕形狀

請注意,這裏的所有代碼都在手錶上運行。另外,我仍然在使用Eclipse,FWIW。

我見過的最簡單的方法是在我的佈局中添加一個onApplyWindowInsets()偵聽器。在我的onCreate()方法

view.setOnApplyWindowInsetsListener(this); 

:所以我創建了一個監聽器,看起來像這樣:

@Override 
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { 
    if (insets.isRound()) { 
    displayShape = "round"; 
    } else { 
    displayShape = "rectangular"; 
    } 
    return null; 
} 

,並把它添加到我的佈局與代碼根視圖這樣。看起來沒問題 - 但聽衆永遠不會被叫到。我還發現一些建議,說我需要手動調用它,因此:

view.requestApplyInsets(); 

但這似乎沒有任何區別。我已經嘗試過將它放在不同的視圖,不同的生命週期方法等等,但從來沒有看到它實際上被我的應用程序調用。這是在我的LG G手錶上運行,BTW。

第二種方法是一種黑客攻擊,它基於已發佈的WatchViewStub輔助類。我通過籃球躍升得到導入到Eclipse項目中的可穿戴的支持庫,然後添加以下到我的根佈局:

<android.support.wearable.view.WatchViewStub 
    android:id="@+id/watch_view_stub" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    app:rectLayout="@layout/rect" 
    app:roundLayout="@layout/round" 
    /> 

創造rect.xml這樣:

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/layout_type" 
    android:text="rectangular" 
    /> 

round.xml這樣:

<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/layout_type" 
    android:text="round" 
    /> 

最後,在我的onCreate()我添加下面的Java代碼:

final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); 
    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { 
     @Override 
     public void onLayoutInflated(WatchViewStub stub) { 
      TextView layoutType = (TextView) findViewById(R.id.layout_type); 
      displayShape = layoutType.getText().toString(); 
     } 
    }); 

這是一段很長的路,但它應該工作,對吧?沒有那麼多...... displayShape始終設置爲"rectangular",表明它始終使用rect.xml,即使在輪循模擬器上運行也是如此。 [我沒有經過全面篩選的硬件,現在就試用它。]

那麼,有沒有人看到我在這兩種方法中哪一種出錯?或者你能建議第三種方法嗎?

回答

12

經過幾天追逐虛假的線索,我終於找到了答案。事實證明,清單中的應用程序的android:theme有所不同。

爲了WatchViewStub使用正確的矩形/圓形佈局,看來,你的應用程序必須使用作爲@android:style/Theme.DeviceDefault主題。這裏有一個例子:

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@android:style/Theme.DeviceDefault"> 

我希望,如果你使用的是從DeviceDefault繼承,雖然我還沒有測試的主題,也將正常工作。但看起來如果您使用任何其他自定義主題,WatchViewStub將無法​​正常工作。

@WaynePiekarski,如果這被記錄在某處它會很好。

另外,這裏有一些小竅門的,我一路上了解到:

  1. 的矩形佈局總是一輪佈局之前膨脹; IOW,在一個圓形的設備上,你會得到兩個onLayoutInflated()回調。這是一種,如果您使用的佈局通脹得到屏幕形狀到您的Java代碼中的痛苦,那真可謂是必要的,因爲......

  2. 調用上WatchViewStubsetOnApplyWindowInsetsListener()防止輪從佈局加載(至少在我的測試中)。因此,如果您嘗試使用此回調來確定屏幕形狀,圓形設備仍然會獲得方形佈局。

最後,獎金問題:有沒有什麼好的理由Android Wear不只是報告其屏幕形狀作爲資源預選賽?你知道,像-land-large等等。爲什麼在地球上,我們需要更動WatchViewStub呢?

+0

感謝您的反饋。我會研究這個主題,看看在這裏可以做些什麼。 – 2014-10-16 06:27:19

+0

對於資源限定符來說,手錶顯示更多的不僅僅是圓形和方形。 Moto 360在圓形顯示屏的底部有一個插圖,而圓形模擬器沒有插頁。所以他們在那裏也不一樣。所以我們使用WindowInsets https://developer.android.com/reference/android/view/WindowInsets.html來編碼顯示器之間的差異。 – 2014-10-16 06:29:04

+0

這絕對是我沒有調用「OnApplyWindowInsetsListener.onApplyWindowInsets()」方法時遇到的問題。 根本原因是我正在構建一個基於'android:Theme'使用主題'GdxTheme'的_libgdx_項目。當我將'GdxTheme'改爲從'@android:style/Theme.DeviceDefault'繼承時,調用了insets回調方法。 這裏是固定版本的'GdxTheme': ''style name =「GdxTheme」parent =「@ android:style/Theme.DeviceDefault」>' – outofcoffee 2014-12-21 19:48:22

1

https://plus.google.com/+NicolasPomepuy/posts/ZJ3KZK6uu2e#+NicolasPomepuy/posts/ZJ3KZK6uu2e

https://github.com/PomepuyN/WatchviewStubIssue/blob/bcad0de7fa473c757dc27f9dfe65e31561c6097f/wear/src/main/java/com/example/watchviewstubissue/ViewService.java

 mainView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { 
51    @Override 
52    public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) { 
53     if (insets.isRound()) { 
54      Log.d("ViewService", "Round"); 
55     } else { 
56      Log.d("ViewService", "Square"); 
57     } 
58     return insets; 
59    } 
60   }); 

的差異你的代碼和他之間是你正在返回空,他將返回插圖。

+0

悉,謝謝。但是這對於是否實際調用'onApplyWindowInsets()'沒有任何影響 - 在我的代碼中進行了此更改後,它仍然不是。 – String 2014-09-03 18:32:16

+0

此外,第一個鏈接中的G +帖子討論了一些有問題的仿真器實例。我不能否認這是一個模擬器問題,但在我的AVD設備列表中,我有4個Android Wear Round實例,它們都給出了相同的結果。 – String 2014-09-03 23:55:29

+0

您應該只有三個AndroidWearRound實例在您的列表中。我不知道你怎麼能有4個,也許你從今年年初開始預覽SDK剩下的剩餘部分?此外,這三個實例並不完全相同,其中一些實際上假裝爲方形設備,而這正在下一個版本中得到解決。確保你使用第二個配置文件,我知道一個工程。否則,你總會得到「方形」作爲你的結果。 – 2014-09-04 00:23:41

2

在CanvasWatchFaceService.Engine他們是一個超越控制方法可用setOnApplyWindowInsets你可以檢查是否鑲石是圓形或方形

@Override 
    public void onApplyWindowInsets(WindowInsets insets) { 
     super.onApplyWindowInsets(insets); 
     if(insets.isRound()){ 
      //round 
     } 
     else{ 
      //square 
     } 

    } 
+0

這與我在我的'onApplyWindowInsets'方法有什麼不同原始帖子,還是9月20日bf2020的回答討論?問題不在於我不知道這種方法,而在於我在代碼中使用了它,而且平臺沒有調用它。 – String 2015-03-10 20:43:23

相關問題