findViewByID returns null

2018-12-31 05:43发布

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:id instead of just id in the XML file. I did.

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

In my location_layout.xml, I use:

<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.findViewById and View.findViewById differences. So I stored the context passed to the customs view constructor locally and tried:

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

which also returned null.

Then, I changed my custom view to extend ViewGroup instead View and changed the location_layout.xml to let the TextView be a direct child of my custom view, so that the View.findViewById should work as supposed. Suprise: it didn't solve anything.

So what the heck am I doing wrong?

I'll appreciate any comments.

27条回答
若你有天会懂
2楼-- · 2018-12-31 06:05

findViewById also can return null if you're inside a Fragment. As described here: findViewById in Fragment

You should call getView() to return the top level View inside a Fragment. Then you can find the layout items (buttons, textviews, etc)

查看更多
不流泪的眼
3楼-- · 2018-12-31 06:06

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

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

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

setContentView(R.layout.main);

instead of

setContentView(R.layout.main2);

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

查看更多
只靠听说
4楼-- · 2018-12-31 06:06

In my experience, it seems that this can also happen when your code is called after OnDestroyView (when the fragment is on the back stack.) If you are updating the UI on input from a BroadCastReceiver, you ought to check if this is the case.

查看更多
孤独寂梦人
5楼-- · 2018-12-31 06:07

Alongside the classic causes, mentioned elsewhere:

  • Make sure you've called setContentView() before findViewById()
  • Make sure that the id you want is in the view or layout you've given to setContentView()
  • Make sure that the id isn't accidentally duplicated in different layouts

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 id attribute works for all the views in the layout except the custom ones. The solution I use is:

  1. Replace each custom view with a FrameLayout with 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.

查看更多
回忆,回不去的记忆
6楼-- · 2018-12-31 06:08
    @Override
protected void onStart() {
         // use findViewById() here instead of in onCreate()
    }
查看更多
人气声优
7楼-- · 2018-12-31 06:08

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

查看更多
登录 后发表回答