Android findViewById() 为布局 XML 中的自定义组件返回 null,而不是其他组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1691569/
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
findViewById() returns null for custom component in layout XML, not for other components
提问by Chris Boyle
I have a res/layout/main.xml
including these elements and others:
我有一个res/layout/main.xml
包括这些元素和其他元素:
<some.package.MyCustomView android:id="@+id/foo" (some other params) />
<TextView android:id="@+id/boring" (some other params) />
In my Activity's onCreate, I do this:
在我的 Activity 的 onCreate 中,我这样做:
setContentView(R.layout.main);
TextView boring = (TextView) findViewById(R.id.boring);
// ...find other elements...
MyCustomView foo = (MyCustomView) findViewById(R.id.foo);
if (foo == null) { Log.d(TAG, "epic fail"); }
The other elements are found successfully, but foo
comes back null. MyCustomView has a constructor MyCustomView(Context c, AttributeSet a)
and a Log.d(...)
at the end of that constructor appears successfully in logcat just before the "epic fail".
其他元素已成功找到,但foo
返回 null。MyCustomView 有一个构造函数,MyCustomView(Context c, AttributeSet a)
并且Log.d(...)
在该构造函数末尾的a在“史诗失败”之前成功出现在 logcat 中。
Why is foo
null?
为什么是foo
空的?
回答by Chris Boyle
Because in the constructor, I had super(context)
instead of super(context, attrs)
.
因为在构造函数中,我有super(context)
而不是super(context, attrs)
.
Makes sense, if you don't pass in the attributes, such as the id, then the view will have no id and therefore not be findable using that id. :-)
有道理,如果您不传入属性,例如 id,那么视图将没有 id,因此无法使用该 id 找到。:-)
回答by Alexander Korolchuk
I have the same problem because in my custom view I overrided constructor but invoked super contructor withot attrs paramete. That is copy paste)
我有同样的问题,因为在我的自定义视图中,我覆盖了构造函数,但调用了没有 attrs 参数的超级构造函数。那是复制粘贴)
My previous constructor version:
我以前的构造函数版本:
public TabsAndFilterRelativeLayout(Context context, AttributeSet attrs) {
super(context);
}
Now I have:
我现在有:
public TabsAndFilterRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);}
And that works!
这有效!
回答by Vincent
I had the same problem. My mistake was that: I wrote
我有同样的问题。我的错误是:我写了
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout=inflater.inflate(R.layout.dlg_show_info, null);
alertDlgShowInfo.setView(layout);
TableRow trowDesc=(TableRow)findViewById(R.id.trowDesc);
and as I used an inflater to "load" the view from an XML file, the last line was wrong. To solve it, I had to write:
当我使用充气器从 XML 文件“加载”视图时,最后一行是错误的。为了解决它,我不得不写:
TableRow trowDesc=(TableRow)layout.findViewById(R.id.trowDesc);
I wrote my solution, in case someone have the same problem.
我写了我的解决方案,以防有人遇到同样的问题。
回答by jellyfish
Seems there is a variety of reasons. I just used "Clean..." in Eclipse to solve a similar problem. (FindViewByID had worked before and for some reason started to return null.)
似乎有各种各样的原因。我只是在 Eclipse 中使用“Clean...”来解决类似的问题。(FindViewByID 以前工作过,由于某种原因开始返回 null。)
回答by Daniel
回答by M.Q.
If you have multiple layout versions (depending on screen densities, SDK versions) make sure that all of them include the element you are looking for.
如果您有多个布局版本(取决于屏幕密度、SDK 版本),请确保所有版本都包含您要查找的元素。
回答by gerfmarquez
In my case findViewById was returning null because my custom view looked something like this in the main XML:
在我的例子中 findViewById 返回 null 因为我的自定义视图在主 XML 中看起来像这样:
<com.gerfmarquez.seekbar.VerticalSeekBar
android:id="@+id/verticalSeekBar"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
/>
and I found out that when I added the xmlns stuff it worked like this:
我发现当我添加 xmlns 的东西时,它是这样工作的:
<com.gerfmarquez.seekbar.VerticalSeekBar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/verticalSeekBar"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
/>
回答by Mason
Be sure that the setContentView(R.layout.main)
statement call before findViewById(...)
statement;
确保setContentView(R.layout.main)
语句在findViewById(...)
语句之前调用;
回答by Stephen Wylie
This happened to me with a custom component for Wear, but is a generic piece of advice. If you're using a Stub (such as I was using WatchViewStub
), you can't just put the call to findViewById()
anywhere. Everything inside the stub must be inflated first, which doesn't just happen after setContentView()
. Thus, you should write something like this in order to wait for that to happen:
这发生在我身上,使用 Wear 的自定义组件,但这是一个通用的建议。如果您使用的是 Stub(例如我使用的WatchViewStub
),则不能只是将调用findViewById()
放在任何地方。存根中的所有内容都必须先膨胀,这不会在setContentView()
. 因此,你应该写这样的东西以等待它发生:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wear);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
myCustomViewInst = (MyCustomView) findViewById(R.id.my_custom_view);
...
回答by Jiwon Park
For me, the problem was solved when I added the res folder to the Source in Java Build Path in project Settings.
对我来说,当我将 res 文件夹添加到项目设置中 Java Build Path 中的 Source 时,问题就解决了。