Programmatically determine screen shape in Android Wear
After several days spent chasing false leads, I've finally found the answer. It turns out that it's the android:theme
of the application in the manifest that makes the difference.
In order for WatchViewStub
to use the correct rect/round layouts, it appears that your application must use @android:style/Theme.DeviceDefault
as its theme. Here's an example:
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.DeviceDefault">
I expect it would also work if you used a theme that inherited from DeviceDefault
, though I haven't tested that. But it appears that if you use any other custom theme, WatchViewStub
will not function correctly.
@WaynePiekarski, it'd be nice if this was documented somehere.
Also, here are a couple of other tips that I learned along the way:
The rectangular layout always inflates before the round layout; IOW, on a round device, you'll get two
onLayoutInflated()
callbacks. This is kind of a pain if you're using the layout inflation to get the screen shape into your Java code, and that turns out to be necessary, because...Calling
setOnApplyWindowInsetsListener()
onWatchViewStub
prevents the round layout from loading at all (at least in my testing). So if you try to use this callback to determine the screen shape, round devices will still get the square layout.
Finally, a bonus question: Is there any good reason why Android Wear doesn't just report its screen shape as a resource qualifier? You know, like -land
, -large
, and so on. Why on earth do we need to mess around with WatchViewStub
at all?
In CanvasWatchFaceService.Engine their is a overide method available setOnApplyWindowInsets you can check whether insets is round or square
@Override
public void onApplyWindowInsets(WindowInsets insets) {
super.onApplyWindowInsets(insets);
if(insets.isRound()){
//round
}
else{
//square
}
}