2014-09-02 76 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

相关问题