受保护的字段对子类不可见

发布于 2024-10-16 06:53:16 字数 784 浏览 3 评论 0原文

我正在编写一个直接扩展android.view.View的自定义视图。如果我尝试访问字段 mScrollXmScrollY,我会看到一条错误,指出该字段“无法解析或不是字段”。 android.view.View 的源代码 具有 mScrollX、mScrollY 和声明为 protected 的类似变量。为什么我的直接子类无法访问其父类的受保护字段? (像 ScrollView 显然可以。)

PS 我意识到我可以调用 getScrollX(),但我想更新这些字段;调用 setScroll() 会产生我不想要的副作用。

I'm writing a custom view that directly extends android.view.View. If I try to access fields mScrollX or mScrollY, I see an error that the field "cannot be resolved or is not a field." The source code for android.view.View has mScrollX, mScrollY, and similar variables declared protected. How is it that my direct subclass cannot access protected fields of its parent class? (Classes like ScrollView apparently can.)

P.S. I realize that I can call getScrollX(), but I want to update these fields; calling setScroll() has side effects that I don't want.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

赠佳期 2024-10-23 06:53:16

这是因为它们不是 Android SDK 的一部分。

以下是 mScrollX 的源代码:

/**
 * The offset, in pixels, by which the content of this view is scrolled
 * horizontally.
 * {@hide}
 */
@ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollX;

您会注意到 @hide 注释。这意味着这不是 Android SDK 的一部分。创建 Android SDK 的构建过程部分不会在 android.view.View 的存根版本中包含此数据成员,该存根版本位于 android.jar 文件中。你正在编译。

@hide 注解用于出于内部目的需要公开或保护但不被视为 SDK 开发人员应该使用的内容。

无论您遇到什么问题,请寻找其他解决方案。

It's because they are not part of the Android SDK.

Here is the source code for mScrollX:

/**
 * The offset, in pixels, by which the content of this view is scrolled
 * horizontally.
 * {@hide}
 */
@ViewDebug.ExportedProperty(category = "scrolling")
protected int mScrollX;

You will notice the @hide annotation. That means this is not part of the Android SDK. The part of the build process that creates the Android SDK will not include this data member in the stub edition of android.view.View that is in the android.jar file that you are compiling against.

The @hide annotation is used for things that for internal purposes needed to be public or protected but are not considered something SDK developers should be using.

Please find other solutions for whatever problem you are experiencing.

忘你却要生生世世 2024-10-23 06:53:16

这非常简单:注意这些变量上方的 @hide 注释。
它是 Android 特定的注释,对公共 SDK 隐藏字段/方法。这就是为什么您无法直接访问它们。

Romain Guy 在这篇文章中提到了这一点。

It's very straight forward: notice the @hide annotation above these variables.
It's an Android-specific annotation that hides the fields/methods from the public SDK. That's why you can't access them directly.

Romain Guy mentioned it in this post.

南巷近海 2024-10-23 06:53:16

您可以尝试使用反射设置字段:

import java.lang.reflect.Field;

// ...

try {
    Field scrollXField = View.class.getDeclaredField("mScrollX");
    scrollXField.setAccessible(true);
    scrollXField.set(this, myNewValue);
} catch (Exception ex) {
    // oops, android changed the implementation. sucks to be you.
}

但是请注意,执行此操作时您依赖于未记录和不受支持的行为,因此您应该做好在某些设备或未来版本中出现问题的准备。

You could try setting the fields with reflection:

import java.lang.reflect.Field;

// ...

try {
    Field scrollXField = View.class.getDeclaredField("mScrollX");
    scrollXField.setAccessible(true);
    scrollXField.set(this, myNewValue);
} catch (Exception ex) {
    // oops, android changed the implementation. sucks to be you.
}

Note, however, that you're relying on undocumented and unsupported behavior when you do this, and so you should be prepared for things to break on some devices or in future versions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文