findViewByID返回null

Tho*_*mas 238 android android-view

首先:是的,我阅读了关于这个主题的所有其他主题.不仅是来自这个网站的人......(你看,我有点沮丧)

他们中的大多数都提供了使用建议,android:id而不仅仅是id在XML文件中.我做到了.

我从其他人那里了解到,View.findViewById与众不同Activity.findViewById.我也是这样处理的.

在我location_layout.xml,我使用:

<FrameLayout .... >
    <some.package.MyCustomView ... />

    <LinearLayout ... >
        <TextView ...
            android:id="@+id/txtLat" />
        ...
    </LinearLayout>
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

在我的活动中,我做了:

...
setContentView( R.layout.location_layout );
Run Code Online (Sandbox Code Playgroud)

在我的自定义视图类中:

... 
TextView tv = (TextView) findViewById( R.id.txtLat );
Run Code Online (Sandbox Code Playgroud)

返回null.这样做,我的活动工作正常.也许这是因为Activity.findViewByIdView.findViewById差异.所以我在本地存储了传递给海关视图构造函数的上下文并尝试:

...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
Run Code Online (Sandbox Code Playgroud)

这也回来了null.

然后,我改变了我的自定义视图扩展ViewGroup,而不是View和改变location_layout.xmlTextView我的自定义视图的直接子,从而使View.findViewById应该工作的设想.惊喜:它没有解决任何问题.

那么我做错了什么?

我会感激任何评论.

Com*_*are 254

返回null

可能是因为你太早称它.等到onFinishInflate().这是一个示例项目,演示View访问其内容的自定义.

  • 我的天啊!不敢相信我花了几天时间做一些如此微不足道的事情.我将setContentView()移到findViewById()调用之上,这就是他的技巧.谢谢! (64认同)
  • 我在findViewById之前调用了setContentView,它仍然是null.我正在引用EditText (3认同)
  • @CommonsWare那是正确的项目吗?我在https://github.com/commonsguy/cw-advandroid/tree/master/Animation/SlidingPanel/中的任何地方都看不到onFinishInflate (2认同)

小智 142

可能,你在打电话findViewById之前打电话setContentView?如果是这样的情况下,尝试调用findViewById 调用setContentView

  • 实际上我有这个错误,因为我调用setContentView指向错误的视图...遗憾的是编译器没有捕获这种类型的错误. (6认同)

小智 98

确保您的布局没有多个版本用于不同的屏幕密度.我在向现有布局添加新ID但忘记更新hdpi版本时遇到此问题.如果您忘记更新布局文件的所有版本,它将适用于某些屏幕密度,但不适用于其他屏幕密度.

  • 谢谢!就是这样.(在我的情况下,我有不同Android版本的多个版本).虽然我在每个布局文件的顶部和底部都放了一个巨大的评论,但我一直都忘了它.如果发生这种情况,我希望编译器会出错或发出重大警告. (7认同)

inf*_*net 15

就我而言,我的项目中有2个活动,main.xml并且main2.xml.从一开始,main2是一个副本main,一切运作良好,直到我添加新TextViewmain2,所以它R.id.textview1可用于其余的应用程序.然后我尝试通过标准调用来获取它:

TextView tv = (TextView) findViewById( R.id.textview1 );
Run Code Online (Sandbox Code Playgroud)

它总是空的.事实证明,在onCreate构造函数中我没有实例化main2,而是另一个实例化.我有:

setContentView(R.layout.main);
Run Code Online (Sandbox Code Playgroud)

代替

setContentView(R.layout.main2);
Run Code Online (Sandbox Code Playgroud)

我到达这里后,在网站上注意到了这一点.


小智 15

如果在自定义视图中调用错误的超级构造函数,则FindViewById可以为null.ID标记是attrs的一部分,因此如果忽略attrs,则删除ID.

这是错误的

public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context);
}
Run Code Online (Sandbox Code Playgroud)

这是对的

public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context,attrs);
}
Run Code Online (Sandbox Code Playgroud)


Nei*_*end 13

除了其他地方提到的经典原因:

  • 请确保你叫setContentView()findViewById()
  • 确保id您想要的是您所提供的视图或布局setContentView()
  • 确保id不会在不同的布局中意外复制

我在标准布局中找到了一个自定义视图,这违反了文档:

理论上,您可以创建自定义视图并将其添加到布局中(请参阅此处).但是,我发现在这种情况下,有时该id属性适用于布局中除自定义视图之外的所有视图.我使用的解决方案是:

  1. 将每个自定义视图替换为具有FrameLayout与自定义视图相同的布局属性.id比如说,给它一个合适的frame_for_custom_view.
  2. onCreate:

    setContentView(R.layout.my_layout);
    FrameView fv = findViewById(R.id.frame_for_custom_layout);
    MyCustomView cv = new MyCustomView(context);
    fv.addView(cv);
    
    Run Code Online (Sandbox Code Playgroud)

    它将自定义视图放在框架中.


Jon*_*han 8

    @Override
protected void onStart() {
         // use findViewById() here instead of in onCreate()
    }
Run Code Online (Sandbox Code Playgroud)


Jos*_*lfe 6

使用ExpandableListView的人的答案,并根据它的标题运行这个问题.

我尝试在我的子视图和组视图中使用TextViews作为ExpandableListView实现的一部分时出现此错误.

您可以在getChildView()和getGroupView()方法的实现中使用类似下面的内容.

        if (convertView == null) {
            LayoutInflater inflater =  (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.child_layout, null);
        }
Run Code Online (Sandbox Code Playgroud)

我在这里找到了这个.


lam*_*345 5

我是Android/Eclipse的新手,错误地我添加了UI的东西activity_main.xml而不是fragment_main.xml.花了我几个小时来搞清楚......


小智 5

FWIW,我看不到有人以与我完全相同的方式解决了这个问题。编译时没有任何抱怨,但是我在运行时得到了一个空视图,并以正确的顺序调用事物。也就是说, setContentView()之后找到 findViewById ()。问题原来是我的视图是在content_main.xml中定义的,但是在我的activity_main.xml中,我缺少这一条语句:

<include layout="@layout/content_main" />
Run Code Online (Sandbox Code Playgroud)

当我将其添加到activity_main.xml时,不再需要NullPointer。