gpt4 book ai didi

android - 为什么将 net.simonvt.numberpicker.NumberPicker 转换为 android.widget.NumberPicker 有效?

转载 作者:行者123 更新时间:2023-11-30 03:36:58 27 4
gpt4 key购买 nike

我有一个使用 NumberPicker 的应用程序。由于该应用程序支持旧版本的 Android,其中没有 NumberPicker 小部件可用,我必须使用 external library .

在我的 XML 布局 numberpicker_dialog.xml 中,我这样定义 NumberPicker:

<net.simonvt.numberpicker.NumberPicker
android:id="@+id/interval_picker_1"
... />

然后在我的 Activity 代码中,我有:

import net.simonvt.numberpicker.NumberPicker;

private View intervalPickerDialogBody;
private NumberPicker intervalPicker1;
private android.widget.NumberPicker api11_intervalPicker1;

protected void onCreate(Bundle savedInstanceState) {

intervalPickerDialogBody = getLayoutInflater()
.inflate(R.layout.numberpicker_dialog, null);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// the casting in question happens here
api11_intervalPicker1 = (android.widget.NumberPicker)
intervalPickerDialogBody.findViewById(R.id.interval_picker_1);
} else {
intervalPicker1 = (NumberPicker)
intervalPickerDialogBody.findViewById(R.id.interval_picker_1);
}

}

它有效,在 Honeycomb 和更新版本上,使用 android.widget.NumberPicker,在旧版本上,使用 net.simonvt.numberpicker.NumberPicker

但是现在我正在写一篇关于使用这个应用程序的论文,我想知道:

  1. 为什么将 net.simonvt.numberpicker.NumberPicker 从 XML 布局转换为 android.widget.NumberPicker 有效,而实际上它们是不同的类?
  2. 当 XML 布局中的 NumberPicker 实际上是来自外部图书馆? android.widget.NumberPicker 的实例何时创建?

android.widget.NumberPicker 在 Honeycomb 和更新版本上使用的事实得到了前面代码 fragment 的第二行在我的 4.0 上等于 true 的事实的支持。 3 电话。

View tmp = intervalPickerDialogBody.findViewById(R.id.interval_picker_1);
tmp instanceof android.widget.NumberPicker // pseudocode

(谢谢你,朱尔斯,这比用箭头击中的证明要好得多。:))

如果有人想知道我怎么知道 android.widget.NumberPicker 实际上用于 Honeycomb 和更新版本,那是因为 net.simonvt.numberpicker.NumberPicker 没有不要在 NumberPicker 上方和下方显示箭头,因为它是从 4.​​2 中反向移植的,其中箭头已被删除。当我在运行 4.0.3 的设备上尝试它时,即使它应该显示 net.simonvt.numberpicker.NumberPicker,箭头仍然存在。

我希望这个问题是可以理解的。感谢您详细说明这个主题。

最佳答案

有趣的问题。这似乎是因为在我看来是 LayoutInflater 中的错误。下面是用于决定将哪个 View 类用于特定 XML 标记的代码:

public final View createView(String name, String prefix, AttributeSet attrs)
throws ClassNotFoundException, InflateException {
Constructor constructor = sConstructorMap.get(name);
Class clazz = null;

try {
if (constructor == null) {
// Class not found in the cache, see if it's real, and try to add it
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name);

if (mFilter != null && clazz != null) {
boolean allowed = mFilter.onLoadClass(clazz);
if (!allowed) {
failNotAllowed(name, prefix, attrs);
}
}
constructor = clazz.getConstructor(mConstructorSignature);
sConstructorMap.put(name, constructor);
}
...

在调用它之前,前缀(即标签名称中直到并包括最后一个点的所有内容)被分离出来并放入前缀参数中,因此对于您的 XML,调用是:

createView ("NumberPicker", "net.simonvt.numberpicker.", ...);

这意味着当 createView 方法在缓存中检查以前使用的构造函数时,只要之前使用过 NumberPicker,它就会返回系统 NumberPicker。

作为我认为这是一个错误的必然结果,我会修改您上面的代码,以防止 future 的 Android 变体修复错误的可能性,方法是使用 instanceof 运算符测试 findViewById 返回的对象类型,而不是你当前的版本号测试,即:

View tmp = intervalPickerDialogBody.findViewById(R.id.interval_picker_1);
if (tmp instanceof android.widget.NumberPicker) { // Note 1 below
api11_intervalPicker1 = (android.widget.NumberPicker)
intervalPickerDialogBody.findViewById(R.id.interval_picker_1);
} else {
intervalPicker1 = (NumberPicker)
intervalPickerDialogBody.findViewById(R.id.interval_picker_1);
}

注意 1 是我假设如果您要检查的类不存在,instanceof 检查不会在运行时崩溃。如果是这样,您将不得不颠倒检查顺序。

关于android - 为什么将 net.simonvt.numberpicker.NumberPicker 转换为 android.widget.NumberPicker 有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16522013/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com