2

我在我的应用程序中有一个为微调器定制的 ArrayAdapter。下面是它的 getDropDownView() 方法的代码:

@Override
    public View getDropDownView(int position, View convertView,ViewGroup parent) {
        View vista = convertView;               
        if (vista==null) {
            LayoutInflater inflater =  (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            vista = inflater.inflate(R.layout.row_spinner,null);
        }

        TextView tv = (TextView) vista.findViewById( R.id.textview_entry );

        if( !Utils.isSDKAbove( Utils.HONEY_COMB ) )
        {
            tv.setTextColor( getContext().getResources().getColor( android.R.color.primary_text_light ) );
        }

        tv.setText( getItem( position ) );

        return vista;
    } 

当 tv.setText() 时,它会为 TextView 抛出 NullPointerException。

但是,当我更改

vista = inflater.inflate(R.layout.row_spinner, null);

vista = inflater.inflate(R.layout.row_spinner, parent, false);

有用。

有人可以解释一下两种不同的方法签名之间的区别吗?

4

1 回答 1

2

通过声明父根视图,您正在为该视图提供父 xml 布局。第三个布尔参数然后确定此子视图是否附加到父视图。从而判断child是否继承了父view的touch方法。

无论哪种方式,都需要根据 xml 布局对视图进行透视,以便您所做的自定义和 xml 结构将在整个视图层次结构中实现。

使用 inflate(layout, parent, false) 您正在使用父布局来膨胀视图(在本例中为微调器)而不将其附加到父视图。使用 null 您没有为视图提供任何布局参数,因此 textview 的 xml 布局参数不存在。

文档

root 可选视图,作为生成的层次结构的父级(如果 attachToRoot 为真),或者只是为返回的层次结构的根提供一组 LayoutParams 值的对象(如果 attachToRoot 为假。)

attachToRoot 膨胀的层次结构是否应该附加到根参数?如果为 false,则 root 仅用于为 XML 中的根视图创建正确的 LayoutParams 子类。

返回
膨胀层次结构的根视图。如果提供了 root 并且 attachToRoot 为真,则这是 root;否则它是膨胀的 XML 文件的根。

使用 null 不是将视图与父视图分离的好方法,除非它是一个独立的功能,例如警报对话框。

视图需要一个根视图,传递 null 有时会起作用,但这只是因为程序试图为视图创建默认的 xml 参数。

这篇文章更详细。

那么,如果我们不应该附加到它,你为什么认为我们会得到这个 ViewGroup 呢?事实证明,父视图是膨胀过程中非常重要的一部分,因为它是评估在被膨胀的 XML 的根元素中声明的 LayoutParams 所必需的。此处不传递任何内容类似于告诉框架“我不知道此视图将附加到哪个父级,抱歉。”</p>

问题是 android:layout_xxx 属性总是在父视图的上下文中进行评估。结果,在没有任何已知父级的情况下,您在 XML 树的根元素上声明的所有 LayoutParams 都将被丢弃,然后您会问“为什么框架忽略了我定义的布局自定义?我最好检查一下 SO,然后提交一个错误。”</p>

于 2015-12-21T08:52:34.653 回答