Android findViewByID返回null

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 ...

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

他们中的大多数人都建议在XML文件中使用
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);