Android findViewByID 返回 null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3264610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:22:38  来源:igfitidea点击:

findViewByID returns null

androidandroid-view

提问by Thomas

First of all: yes, I read all the other threads on this topic. And not only those from this site... (you see, I'm a little frustrated)

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

Most of them come with the advice to use android:idinstead of just idin the XML file. I did.

它们中的大多数都带有要使用的建议,android:id而不仅仅是id在 XML 文件中。我做到了。

From others, I learned, that View.findViewByIdworks different than Activity.findViewById. I handled that, too.

我从其他人那里了解到,这View.findViewByIdActivity.findViewById. 我也是这样处理的。

In my location_layout.xml, I use:

在我的location_layout.xml,我使用:

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

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

In my Activity I do:

在我的活动中,我这样做:

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

and in my custom view class:

在我的自定义视图类中:

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

which returns null. Doing this, my Activity works fine.So maybe it's because of the Activity.findViewByIdand View.findViewByIddifferences. So I stored the context passed to the customs view constructor locally and tried:

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

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

which also returned null.

这也返回了null

Then, I changed my custom view to extend ViewGroupinstead Viewand changed the location_layout.xmlto let the TextViewbe a direct child of my custom view, so that the View.findViewByIdshould work as supposed. Suprise: it didn't solve anything.

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

So what the heck am I doing wrong?

那我到底做错了什么?

I'll appreciate any comments.

我将不胜感激任何意见。

回答by CommonsWare

which returns null

返回空值

Possibly because you are calling it too early. Wait until onFinishInflate(). Here is a sample projectdemonstrating a custom Viewaccessing its contents.

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

回答by Bayram Boyraz

Possibly, you are calling findViewByIdbefore calling setContentView? If that's the case, try calling findViewByIdAFTERcalling setContentView

可能,你在打电话findViewById之前先打电话setContentView?如果是这种情况,请尝试在调用findViewById调用setContentView

回答by Joe

Make sure you don't have multiple versions of your layout for different screen densities. I ran into this problem once when adding a new id to an existing layout but forgot to update the hdpi version. If you forget to update all versions of the layout file it will work for some screen densities but not others.

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

回答by repkap11

FindViewById can be null if you call the wrong super constructor in a custom view. The ID tag is part of attrs, so if you ignore attrs, you delete the ID.

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

This would be wrong

这是错误的

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

This is correct

这是对的

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

回答by infografnet

In my case, I had 2 activites in my project, main.xmland main2.xml. From the beginning, main2was a copy of main, and everything worked well, until I added new TextViewto main2, so the R.id.textview1became available for the rest of app. Then I tried to fetch it by standard calling:

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

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

and it was always null. It turned out, that in onCreateconstructor I was instantiating not main2, but the other one. I had:

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

setContentView(R.layout.main);

instead of

代替

setContentView(R.layout.main2);

I noticed this after I arrived here, on the site.

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

回答by Neil Townsend

Alongside the classic causes, mentioned elsewhere:

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

  • Make sure you've called setContentView()before findViewById()
  • Make sure that the idyou want is in the view or layout you've given to setContentView()
  • Make sure that the idisn't accidentally duplicated in different layouts
  • 请确保您已被称为setContentView()findViewById()
  • 确保id您想要的在您提供的视图或布局中setContentView()
  • 确保id不会在不同的布局中意外重复

There is one I have found for custom views in standard layouts, which goes against the documentation:

我在标准布局中找到了一个自定义视图,它与文档背道而驰:

In theory you can create a custom view and add it to a layout (see here). However, I have found that in such situations, sometimes the idattribute works for all the views in the layout except the custom ones. The solution I use is:

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

  1. Replace each custom view with a FrameLayoutwith the same layout properties as you would like the custom view to have. Give it an appropriate id, say frame_for_custom_view.
  2. In onCreate:

    setContentView(R.layout.my_layout);
    FrameView fv = findViewById(R.id.frame_for_custom_layout);
    MyCustomView cv = new MyCustomView(context);
    fv.addView(cv);
    

    which puts the custom view in the frame.

  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);
    

    将自定义视图放入框架中。

回答by Jonathan

    @Override
protected void onStart() {
         // use findViewById() here instead of in onCreate()
    }

回答by Josh Metcalfe

A answer for those using ExpandableListView and run into this question based on it's title.

那些使用 ExpandableListView 并根据标题遇到这个问题的人的答案。

I had this error attempting to work with TextViews in my child and group views as part of an ExpandableListView implementation.

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

You can use something like the following in your implementations of the getChildView() and getGroupView() methods.

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

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

I found this here.

我在这里找到了这个。

回答by lama12345

I'm pretty new to Android/Eclipse, by mistake I added the UI stuff to activity_main.xmlinstead of fragment_main.xml. Took me some hours to figure that out...

我对 Android/Eclipse 还很陌生,我错误地将 UI 内容添加到activity_main.xmlfragment_main.xml. 我花了几个小时才弄清楚...

回答by ferris

FWIW, I don't see that anyone solved this in quite the same way as I needed to. No complaints at compile time, but I was getting a null view at runtime, and calling things in the proper order. That is, findViewById() aftersetContentView(). The problem turned out that my view is defined in content_main.xml, but in my activity_main.xml, I lacked this one statement:

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

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

When I added that to activity_main.xml, no more NullPointer.

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