2011-02-06 92 views
15

我正在写一个自定义视图,它可以直接扩展android.view.View。如果我尝试访问mScrollXmScrollY字段,则会看到“无法解析或不是字段”字段的错误。 source code for android.view.View有mScrollX,mScrollY和类似的变量protected。我的直接子类如何不能访问其父类的受保护字段? (类似ScrollView显然可以。)受保护的字段对子类不可见

P.S.我意识到我可以致电getScrollX(),但我想更新这些字段;调用setScroll()有副作用,我不想要。

+0

奇怪的是,即使在其他包中,子类也可以访问其超类的受保护变量。我猜你会使用错误的版本。你能展示一些你的代码吗? – 2011-02-06 21:28:34

+0

行为已确认。 – 2011-02-06 21:30:34

回答

20

这是因为它们不是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.jar文件中的存根版android.view.View中。

@hide注释用于内部目的需要公开或受保护但不被认为是SDK开发人员应该使用的东西。

请为您遇到的任何问题找到其他解决方案。

+9

嗯,有趣!因此,为了解释理由:“我们无法理清适当的封装,所以我们颠覆了语言。”... – 2011-02-06 21:53:02

5

这非常直截了当:注意这些变量上方的@hide注释。 这是一个特定于Android的注释,它隐藏了公共SDK中的字段/方法。这就是为什么你无法直接访问它们的原因。

Romain Guy mentioned it in此主题。

4

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

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. 
} 

但是请注意,您所依靠无证和不支持的行为,当你这样做,所以你要的东西打破准备在某些设备上或将来的版本中。