有没有办法检测时钟是否是圆形的?

22

我可能错过了些什么,但是是否有标志来确定时钟是圆形还是方形?

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


我写了一份关于接收窗口插图的简短指南:http://gruszczy.blogspot.com/2015/03/handling-round-screens-using.html - gruszczy
7个回答

23

API 23更新:

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

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

Android 参考文档

或者您可以使用 roundnotround 资源限定符,并让系统应用适当的资源。但请注意,这将无法在运行 API 22 或更低版本的设备上工作。

来源

感谢指出这一变化的人们。

旧答案

从 Google 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
    }

}

1
有任何想法如何让这个回调函数被触发吗?我已经将OnApplyWindowInsetsListener添加到了我的根视图上,但是onApplyWindowInsets()从未被调用。另外一个SO文章建议我手动在该视图上调用requestApplyInsets(),但那也没什么帮助。 - Sterling
我只看到过在设备是圆形时才调用这个方法。现在似乎唯一使其正常工作的方法是在设置监听器之前设置“方形默认值”,然后仅在监听器中设置圆形值。 - Jherico
这里我创建了一个小类,简化了使用它的过程 - https://github.com/tajchert/ShapeWear - Michał Tajchert
请切换到资源限定符“-round”和/或使用getResources().getConfiguration().isScreenRound()。 - Mark Renouf

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"/>

当然,您也可以只使用一个字符串: < p > < strong > < em > < code > 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


3
您可能需要使用WatchViewStub,该组件包含在wearable-support库中。在该组件中,您需要指定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是用于矩形和圆形显示器的不同布局。

在Activity中:

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是谷歌闭源的Android Wear库的一部分。该库的API并不被所有Android手表支持,特别是在廉价的中国OEM型号中。在使用WatchViewStub之前,请确保您的目标手表支持Android Wear。此外,从API 23开始,WatchViewStub已被弃用,并且有更好的替代方法可用(https://android-developers.googleblog.com/2016/04/build-beautifully-for-android-wear.html)。 - Farrukh Najmi

1

根据IonSpin的回答,下面这几行代码可以正常工作:

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

0

我的设备上windowinsets方法失败了,所以我使用了一个小技巧,虽然不太美观但是很实用。
如果你需要在activity中检查,则可以在布局中添加一个隐藏的textview,其值为"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());

1
API 23+:getResources().getConfiguration().isScreenRound() - Mark Renouf
太好了!终于有一种本地的方法可以做到这一点了!感谢Mark Renouf。 - Ignacio Tomas Crespo

0

我想在这里加上我的两分钱,因为我认为我找到了一个解决方案,虽然有点愚蠢,但非常简单和直接。

为什么? 首先,@IonSpin提出的两个解决方案都完美地工作,但第一个需要SDK 23以上,而另一个是异步的...

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

<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: is not round ? true

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

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

你们能否确认它也适用于您?


-1

如果我理解正确的话,它将使用标准的Android资源,这意味着你只需要把你的布局放在layout-circle中就可以了。


我猜我会把我的图片放在drawable-circle里。现在我收到了错误信息:*invalid resource directory name: [...]\build\res\all\debug/drawable-circle*。所以我想你是错的。 - rekire
@rekire 这只是开发者预览版,平台在发布之前会有所改变。因此,我并不惊讶工具还不支持这个功能。 - Stefan Hoth
有道理。如果这个答案对我有用,我才会接受它,但在此期间+1;-) - rekire
1
OnApplyWindowInsets是一个类,用于报告设备是否为圆形或正方形! - Paresh Mayani
从API 23开始,这些后缀是-round和-notround。 - rekire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接