首先,是的,我读了关于这个话题的所有其他帖子。不仅仅是这个网站的人…(你看,我有点沮丧)

大多数都建议使用android:id,而不是XML文件中的id。我做到了。

我从别人那里了解到,这种观点。findViewById的工作方式与Activity.findViewById不同。我也处理了。

在我的location_layout.xml中,我使用:

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

    <LinearLayout ... >
        <TextView ...
            android:id="@+id/txtLat" />
        ...
    </LinearLayout>
</FrameLayout>

在我的活动中,我做:

...
setContentView( R.layout.location_layout );

在我的自定义视图类中:

... 
TextView tv = (TextView) findViewById( R.id.txtLat );

返回null。这样做,我的Activity工作得很好。所以这可能是因为活动。findViewById和View。findViewById差异。所以我存储上下文传递给本地的海关视图构造函数,并尝试:

...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );

它也返回null。

然后,我改变了我的自定义视图扩展ViewGroup而不是视图,并改变了location_layout.xml,让TextView是我的自定义视图的直接子,以便视图。findViewById应该正常工作。令人惊讶的是:它并没有解决任何问题。

我到底做错了什么?

欢迎任何意见。


当前回答

在我的特殊情况下,我试图添加一个页脚到一个ListView。onCreate()中的下面调用返回null。

TextView footerView = (TextView) placesListView.findViewById(R.id.footer);

将此更改为膨胀页脚视图,而不是通过ID查找它解决了这个问题。

View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false);

其他回答

根据我的经验,这似乎也会发生在你的代码被调用后OnDestroyView(当片段是在后面的堆栈)。如果您正在根据BroadCastReceiver的输入更新UI,则应该检查是否存在这种情况。

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

这是错误的

public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context);
}

这是正确的

public CameraSurfaceView(Context context, AttributeSet attrs) {
        super(context,attrs);
}

我只是想把我的具体案子提出来。也许能帮到别人。

我使用的指令在我的Android UI XML像这样:

父视图:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="home_phone"
    android:background="@color/colorPrimary">

    ...

    <include
        layout="@layout/retry_button"
        android:visibility="gone" />

子视图(retry_button):

<com.foo.RetryButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/retry"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:layout_width="100dp"
    android:layout_height="140dp">

. findviewbyid (R.id.retry)将总是返回null。但是,如果我把ID从子视图移到include标签,它就开始工作了。

固定的家长:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:tag="home_phone"
    android:background="@color/colorPrimary">

    ...

    <include
        layout="@layout/retry_button"
        android:id="@+id/retry"
        android:visibility="gone" />

固定的孩子:

<com.foo.RetryButton
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:layout_width="100dp"
    android:layout_height="140dp">

在我的例子中,我的项目中有两个活动,main.xml和main2.xml。从一开始,main2是main的副本,一切都工作得很好,直到我添加了新的TextView到main2,所以R.id。textview1成为可用的应用程序的其余部分。然后我试图通过标准调用获取它:

TextView tv = (TextView) findViewById( R.id.textview1 );

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

setContentView(R.layout.main);

而不是

setContentView(R.layout.main2);

我到这里后,在工地上注意到了这一点。

FWIW,我没有看到任何人解决这个问题在完全相同的方式,我需要。在编译时没有抱怨,但我在运行时得到一个空视图,并以适当的顺序调用东西。也就是说, findViewById () 后 setContentView()。 问题是,我的视图是在content_main.xml中定义的,但在我的activity_main.xml中,我缺少这一条语句:

<include layout="@layout/content_main" />

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