Android findViewByID返回null
首先:是的,我阅读了关于这个主题的所有其他文章。不仅是来自这个网站的人。。。(你看,我有点沮丧) 他们中的大多数人都建议在XML文件中使用Android findViewByID返回null,android,android-view,Android,Android View,首先:是的,我阅读了关于这个主题的所有其他文章。不仅是来自这个网站的人。。。(你看,我有点沮丧) 他们中的大多数人都建议在XML文件中使用android:id,而不仅仅是id。是的 我从其他人那里了解到,View.findViewById的工作原理不同于Activity.findViewById。我也处理过 在我的location\u layout.xml中,我使用: <FrameLayout .... > <some.package.MyCustomView ...
android:id
,而不仅仅是id
。是的
我从其他人那里了解到,View.findViewById
的工作原理不同于Activity.findViewById
。我也处理过
在我的location\u layout.xml
中,我使用:
<FrameLayout .... >
<some.package.MyCustomView ... />
<LinearLayout ... >
<TextView ...
android:id="@+id/txtLat" />
...
</LinearLayout>
</FrameLayout>
在我的自定义视图类中:
...
TextView tv = (TextView) findViewById( R.id.txtLat );
返回null
这样做,我的活动效果很好。所以可能是因为活动.findViewById
和视图.findViewById
的不同。因此,我在本地存储了传递给customs view构造函数的上下文,并尝试:
...
TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat );
它还返回了null
然后,我将自定义视图更改为扩展ViewGroup
,而不是view
,并更改了location\u layout.xml
,使TextView
成为自定义视图的直接子视图,以便视图.findViewById
可以正常工作。令人惊讶的是:它没有解决任何问题
那我到底做错了什么
如有任何意见,我将不胜感激
返回空值
可能是因为你打电话太早了。等待,直到完成充气()。演示自定义的
视图
访问其内容。确保不同屏幕密度的布局没有多个版本。我曾经在向现有布局添加新id时遇到过这个问题,但忘记了更新hdpi版本。如果您忘记更新布局文件的所有版本,它将适用于某些屏幕密度,但不适用于其他屏幕密度。在调用setContentView
之前,您可能正在调用findViewById
?
如果是这种情况,请在调用setContentView
为使用ExpandableListView的用户提供答案后,尝试调用findViewById
,并根据标题运行此问题
作为ExpandableListView实现的一部分,我尝试在我的子视图和组视图中使用TextView时出错
在getChildView()和getGroupView()方法的实现中,可以使用如下内容
我发现了这一点。在我的例子中,我使用的是ExpandableListView,我已经设置了
android:transcriptMode=“normal”
。这导致expandable group中的几个子项消失,我使用滚动列表时,常常会出现空异常。在我的项目中,我有两个活动,main.xml
和main2.xml
。从一开始,main2
就是main
的副本,一切都很好,直到我在main2
中添加了新的TextView
,所以R.id.textview1
就可以在应用程序的其余部分使用了。然后我尝试通过标准调用获取它:
TextView tv = (TextView) findViewById( R.id.textview1 );
它总是空的。事实证明,在onCreate
构造函数中,我实例化的不是main2
,而是另一个。我有:
setContentView(R.layout.main);
而不是
setContentView(R.layout.main2);
在我到达这里后,我在网站上注意到了这一点。对于我来说,我有两个用于相同活动的xml布局——一个是纵向模式,另一个是横向模式。当然,我已经在横向xml中更改了对象的id,但忘记在纵向版本中进行相同的更改。确保如果您更改了一个xml,您也会对另一个xml执行相同的操作,否则在您运行/调试它并且它找不到您未更改的id之前,不会出现错误。哦,愚蠢的错误,你为什么一定要惩罚我呢?根据我的经验,当你的代码在OnDestroyView之后被调用时(当片段在后堆栈上时),这种情况似乎也会发生。如果你是根据广播接收器的输入更新UI,你应该检查是否是这样的情况。我对Android/Eclipse非常陌生,我错误地将UI内容添加到
activity\u main.xml
而不是fragment\u main.xml
。我花了几个小时才弄明白…从版面资源设置活动内容。
@Override
protected void onStart() {
// use findViewById() here instead of in onCreate()
}
例如,
setContentView(R.layout.basicXml)
我也有同样的问题。我使用的是第三方库,它允许您覆盖GridView的适配器,并为每个GridView单元指定自己的布局
我终于意识到发生了什么。Eclipse仍然为GridView中的每个单元格使用库的布局xml文件,尽管它没有给出这方面的指示。在我的自定义适配器中,它表示它正在使用我自己项目中的xml资源,即使在运行时不是这样
因此,我所做的是确保我的自定义xml布局和ID与库中的不同,清理项目,然后它开始读取项目中正确的自定义布局
简言之,如果要覆盖第三方库的适配器并为适配器指定自己的布局xml,请务必小心。如果项目中的布局与库中的布局具有相同的文件名,则可能会遇到很难找到的错误 除了其他地方提到的经典原因之外:
- 确保在
findViewById()之前调用了
setContentView()
- 确保所需的
位于您提供给id
setContentView()的视图或布局中
- 确保
不会在不同的布局中意外重复id
id
属性有时适用于布局中的所有视图,自定义视图除外。我使用的解决方案是:
FrameLayout
setContentView(R.layout.main2);
@Override
protected void onStart() {
// use findViewById() here instead of in 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 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);
...
}
TextView footerView = (TextView) placesListView.findViewById(R.id.footer);
View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false);
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context);
}
public CameraSurfaceView(Context context, AttributeSet attrs) {
super(context,attrs);
}
public class MiniPlayerControllBar extends LinearLayout {
//code
}
<ListView
android:id="@+id/listview">
<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" />
<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">
<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">
<include layout="@layout/content_main" />
Spinner hdSpinner = (Spinner)view.findViewById(R.id.accountsSpinner);
mTransactionAdapter = new TransactionAdapter(getActivity(),
R.layout.transactions_list_item, null, from, to, 0, hdSpinner);
password = (EditText)findViewById(R.id.r_password);
public View getView(int i, View view, ViewGroup viewGroup) {
// Gets the inflater
LayoutInflater inflater = LayoutInflater.from(this.contexto);
// Inflates the layout
ConstraintLayout cl2 = (ConstraintLayout)
inflater.inflate(R.layout.custom_list_view, viewGroup, false);
//Insted of calling just findViewById, I call de cl2.findViewById method. cl2 is the layout I have just inflated.
TextView tv1 = (TextView)cl2.findViewById(cl2);