findViewByID返回null
首先:是的,我读了关于这个话题的所有其他线索。 而且不仅来自这个网站的人(你看,我有点沮丧)
他们中的大多数都带有build议在XML文件中使用android:id
而不是id
。 我做了。
从其他人那里,我了解到, View.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
而不是View
并更改了location_layout.xml
,让TextView
成为我的自定义视图的直接子View.findViewById
,这样View.findViewById
可以按照假设工作。 惊喜:没有解决任何问题。
那么,我做错了什么?
我会感激任何意见。
它返回null
可能是因为你说这个太早了。 等到onFinishInflate()
。 这是一个示例项目,展示了访问其内容的自定义View
。
可能你在调用setContentView
之前调用了findViewById
? 如果是这种情况,请尝试在调用setContentView
之后调用findViewById
确保你没有多个版本的你的布局不同的屏幕密度。 在向现有布局添加新的ID时,我遇到了这个问题,但忘记了更新hdpi版本。 如果您忘记更新布局文件的所有版本,它将适用于某些屏幕密度,但不适用于其他屏幕密度。
就我而言,我的项目中有两个活动, 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);
我到达这里后,在网站上注意到了这一点。
除了其他经典的原因外,
- 确保你在
findViewById()
之前调用了setContentView()
findViewById()
- 确保你想要的
id
在你给setContentView()
的视图或布局中, - 确保
id
不会在不同的布局中意外重复
有一个我发现自定义视图在标准布局,这是违背的文档:
从理论上讲,你可以创build一个自定义的视图,并将其添加到布局( 见这里 )。 但是,我发现在这种情况下,有时候id
属性对于布局中的所有视图都起作用,除了自定义视图之外。 我使用的解决scheme是:
- 将每个自定义视图replace为具有与自定义视图相同的布局属性的
FrameLayout
。 给它一个适当的id
,说frame_for_custom_view
。 -
在
onCreate
:setContentView(R.layout.my_layout); FrameView fv = findViewById(R.id.frame_for_custom_layout); MyCustomView cv = new MyCustomView(context); fv.addView(cv);
将自定义视图放在框架中。
@Override protected void onStart() { // use findViewById() here instead of in onCreate() }
如果您在自定义视图中调用错误的超级构造函数,则FindViewById可以为null。 ID标签是attrs的一部分,所以如果你忽略attrs,你删除了ID。
这将是错误的
public CameraSurfaceView(Context context, AttributeSet attrs) { super(context); }
这是对的
public CameraSurfaceView(Context context, AttributeSet attrs) { super(context,attrs); }
对于那些使用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); }
我在这里find了 。
我很新的Android / Eclipse,错误我将UI的东西添加到activity_main.xml
而不是fragment_main.xml
。 花了我几个小时来弄清楚
在我的特殊情况下,我试图添加一个页脚到ListView。 在onCreate()中的以下调用返回null。
TextView footerView = (TextView) placesListView.findViewById(R.id.footer);
改变这个来扩大页脚视图,而不是通过IDfind它解决了这个问题。
View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false);
FWIW,我没有看到任何人以我需要的方式解决这个问题。 在编译时没有任何抱怨,但是我在运行时得到一个空视图,并以正确的顺序调用事物。 即在 setContentView() 之后的 findViewById()。 问题结果是,我的观点是在content_main.xml中定义的,但在我的activity_main.xml中,我缺less这样一个说法:
<include layout="@layout/content_main" />
当我将其添加到activity_main.xml时,不再需要NullPointer。
在我的例子中,我使用ExpandableListView,并设置了android:transcriptMode="normal"
。 这导致可扩展组中的几个孩子消失,而且当我使用滚动列表的时候,我曾经得到NULLexception。
对于我来说,我有两个相同的活动的XML布局 – 一个肖像模式和一个景观。 当然,我已经改变了风景xml中的一个对象的id,但忘记了在肖像版本中做同样的改变。 确保如果你改变一个你做相同的另一个XML或者你不会得到一个错误,直到你运行/debugging它,它不能find你没有改变的ID。 哦,愚蠢的错误,为什么你要惩罚我呢?
设置布局资源的活动内容。 即, setContentView(R.layout.basicXml)
;
我有这个相同的问题。 我正在使用第三方库,允许您覆盖GridView的适配器,并为每个GridView单元指定您自己的布局。
我终于意识到发生了什么事情。 对于GridView中的每个单元,Eclipse仍然使用该库的布局xml文件,尽pipe它没有提供任何指示。 在我的自定义适配器中,它表示它正在使用我自己的项目中的xml资源,即使在运行时,它也不是。
所以我所做的是确保我的自定义xml布局和id与仍在库中的xml布局和id不同,清理了项目,然后开始读取项目中正确的自定义布局。
简而言之,如果您要覆盖第三方库的适配器并指定您自己的布局xml供适配器使用,请小心。 如果您的项目中的布局与库中的文件名相同,则可能会遇到一个非常难以发现的错误!
除了上面的解决scheme,你确保
tools:context=".TakeMultipleImages"
在tools:context=".TakeMultipleImages"
文件中是相同的值:
android:name=".TakeMultipleImages"
为同一个activity元素。 在使用复制和粘贴来创build新活动时发生
我有同样的问题,但我认为它值得与你们分享。 如果必须在自定义布局中findViewById,例如:
public class MiniPlayerControllBar extends LinearLayout { //code }
你不能在构造函数中获取视图。 充值后应该调用findViewById。 他们是一个方法,你可以覆盖onFinishInflate
在我的情况下,我膨胀了布局,但子视图返回null。 本来我有这个:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_history); footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false); pbSpinner = (ProgressBar) findViewById(R.id.pbListviewFooter); tvText = (TextView) findViewById(R.id.tvListviewFooter); ... }
但是,当我改变它到以下它的工作:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_history); footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false); pbSpinner = (ProgressBar) footerView.findViewById(R.id.pbListviewFooter); tvText = (TextView) footerView.findViewById(R.id.tvListviewFooter); ... }
关键是要具体引用已经膨胀的布局,以获得孩子的意见。 也就是说,添加footerView
:
- footerView .findViewById …
我已经尝试了以上所有没有工作..所以我不得不使我的ImageView静态 public static ImageView texture;
然后texture = (ImageView) findViewById(R.id.texture_back);
,我不认为这是一个很好的方法,但这真的为我的情况:)
根据我的经验,当你的代码在OnDestroyView之后被调用(当这个片断在栈上时),这似乎也会发生。如果你正在更新来自BroadCastReceiver的input的UI,你应该检查是否是这种情况。
填充布局! (其中包含的ID)
在我的情况findViewById()返回null,因为元素被写入的布局,没有膨胀…
例如。 fragment_layout.xml
<ListView android:id="@+id/listview">
findViewById(R.id.listview)返回null,因为我没有做inflater.inflate(R.layout.fragment_layout,…,…); 在它之前。
希望这个答案有助于你们一些。
我的修复只是清理项目。
只是想在这里抛出我的具体情况。 可能帮助某人下线。
我在我的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从子视图移动到包含标记,它开始工作。
固定父:
<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">
如果你在一个片段内,findViewById也可以返回null。 如下所述: 在Fragment中的findViewById
你应该调用getView()来返回片段中的顶层View。 然后你可以find布局项目(button,文本浏览等)