【问题标题】:Is there any way to detect if the clock is round?有没有办法检测时钟是否是圆的?
【发布时间】:2014-03-20 06:53:33
【问题描述】:

可能我错过了什么,但有什么标志可以知道时钟是圆形还是方形?

如果你想设计通知的背景,我可以想象这很重要。

【问题讨论】:

标签: android wear-os


【解决方案1】:

API 23 更新:

要确定屏幕是否为圆形,您可以使用

context.getResources().getConfiguration().isScreenRound()

Android reference

或者您可以使用 roundnotround 资源限定符并让系统应用适当的资源,但请注意这不适用于运行 API 22 或更低版本的设备

Source

感谢指出这一变化的人。

旧版本

来自谷歌 I/O 谈话 (https://www.youtube.com/watch?v=naf_WbtFAlY#t=284):

从 SDK 20 android.view.View 类有

public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener)

OnApplyWindowInsetsListener有一个回调方法onApplyWindowsInset

public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets){

    if (windowInsets.isRound()){
        //Do stuff
    }

}

【讨论】:

  • 知道如何让这个回调真正触发吗?我已将 OnApplyWindowInsetsListener 添加到我的根视图中,但从未调用过 onApplyWindowInsets()。另一篇 SO 帖子建议我需要在该视图上手动调用 requestApplyInsets() ,但这也无济于事。
  • 我只见过在设备是圆形的情况下调用的方法。似乎现在让它正常工作的唯一方法是在设置监听器之前设置“方形默认值”,然后只在监听器中设置圆形值。
  • 在这里我创建了一个小类来简化使用它 - github.com/tajchert/ShapeWear
  • 请切换到资源限定符“-round”和/或getResources().getConfiguration().isScreenRound()
【解决方案2】:

您可能想要使用 WatchViewStub,它包含在可穿戴设备支持库中。在存根中,您指定一个roundLayout 和rectLayout,正确的一个会根据用户的屏幕形状自动膨胀。有关如何执行此操作的示例,请参阅 SDK 中包含的 WatchViewStub 示例应用程序。

编辑: 可穿戴样本的源代码现已上线。对于这种情况,请查看 WatchViewStub 示例,它“演示了如何为圆形和矩形屏幕指定不同的布局”:https://developer.android.com/samples/WatchViewStub/project.html

快速参考:

在布局中:

    <android.blah.WatchViewStub
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:rectLayout="@layout/rect"
        app:roundLayout="@layout/round" />

其中 rect 和 round 是矩形和圆形显示器的不同布局。

在活动中:

setContentView(R.layout.main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
    @Override
    public void onLayoutInflated(WatchViewStub stub) {
        mTextView = (TextView) stub.findViewById(R.id.text);
        Log.d(TAG, "TextView: " + mTextView.getText() + " view=" + mTextView);
    }
});

onLayoutInflated 是可选的,但它可以让您查看被膨胀的布局中的哪些内容,因此您可以根据 WatchViewStub 选择膨胀的布局(矩形或圆形)进行额外的自定义。

【讨论】:

  • WatchViewStub 是 google 的闭源 Android Wear 库的一部分。并非所有 Android 手表都支持此库中的 API,尤其是更便宜的中国 OEM 型号。在使用 WatchViewStub 之前,请确保您的目标手表支持 Android Wear。从 API 23 开始不推荐使用 WatchViewStub,并且有 better ways available
【解决方案3】:

从 API 23 开始,您可以使用 -round-notround 资源限定符。所以在几周内不需要使用WatchViewStub

就以这个布局为例:

layout-round/example.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="@string/round_string"/>

layout-notround/example.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="@string/square_string"/>

当然你也可以只使用一个字符串:

layout/example.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:text="@string/string"/>

values-round/strings.xml

<resources>
    <string name="string">I am round</string>
</resources>

values-notround/strings.xml

<resources>
    <string name="string">I am square</string>
</resources>

source

【讨论】:

    【解决方案4】:

    IonSpin's answer 之后,以下几行可以正常工作:

        if (getResources().getConfiguration().isScreenRound()) {
            //code for round wearables
        } else {
            //code for notround wearables
        }
    

    【讨论】:

      【解决方案5】:

      windowinsets 方法在我的设备中失败了,所以我做了一个小技巧,虽然丑陋但很实用。
      如果您需要检查活动内部,请在布局中添加一个隐藏的文本视图,其值为圆形布局中的 "1" 和矩形布局中的 "0"

      <TextView
          android:id="@+id/isRound"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:visibility="gone"
          android:text="1" />
      

      然后在活动中:

      TextView isRoundText = (TextView) view.findViewById(R.id.isRound);
      boolean isRound = "1".equals(isRoundText.getText());
      

      【讨论】:

      • API 23+:getResources().getConfiguration().isScreenRound()
      • 太好了!最后,我们有一种本地方式来做到这一点!谢谢马克雷诺夫
      【解决方案6】:

      我想在这里添加我自己的两分钱,因为我认为我找到了一个解决方案,虽然有点笨拙,但相当简单明了。

      为什么? 首先,@IonSpin 公开的两种解决方案都可以完美运行,但第一种要求 SDK 最低 23,另一种是异步的...

      使用-round-notround 限定符,只需在layout-round 文件夹内的Activity XML 布局中添加一个虚拟空视图,如下所示:

      <View
          android:layout_width="0dp"
          android:layout_height="0dp"
          android:id="@+id/isRound"/>
      

      然后在你的 Activity onCreate() 中,简单的做:

      Log.d(TAG, "is not round ? " + (findViewById(R.id.isRound) == null));
      

      它应该打印在方形智能手表上:

      MainActivity:不是圆形的吗?真的

      作为 Android Wear 的新开发者,我觉得这个解决方案有点难以置信,但它确实适用于我的 Sony SmartWatch 3 和虚拟圆形 Android Wear 设备。

      这里唯一的缺点/权衡是您必须在所有布局中放置一个虚拟视图...

      你们能确认它也适合你吗?

      【讨论】:

        【解决方案7】:

        如果我理解正确,它将使用标准 Android 资源,这意味着您只需将布局放入 layout-circle 即可。

        【讨论】:

        • 我想我会把我的图片放在drawable-circle。我现在收到错误消息:invalid resource directory name: [...]\build\res\all\debug/drawable-circle。所以我猜你错了。
        • @rekire 这是一个开发者预览版,平台会在发布前发生变化。所以我对这些工具还不支持这一点并不感到惊讶。
        • 有道理。如果它对我有用,我只会接受这个答案,但与此同时 +1 ;-)
        • OnApplyWindowInsets 是报告设备是圆形还是方形的类!
        • 从 API 23 开始,这些后缀是 -round 和 -notround。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-01
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-19
        相关资源
        最近更新 更多