首先,是的,我读了关于这个话题的所有其他帖子。不仅仅是这个网站的人…(你看,我有点沮丧)

大多数都建议使用android:id,而不是XML文件中的id。我做到了。

我从别人那里了解到,这种观点。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而不是视图,并改变了location_layout.xml,让TextView是我的自定义视图的直接子,以便视图。findViewById应该正常工作。令人惊讶的是:它并没有解决任何问题。

我到底做错了什么?

欢迎任何意见。


当前回答

在我的情况下,我已经膨胀布局,但子视图返回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……

其他回答

返回null

可能是因为你说得太早了。等待到onfinishinflation()。下面是一个示例项目,演示了一个自定义视图访问其内容。

根据我的经验,这似乎也会发生在你的代码被调用后OnDestroyView(当片段是在后面的堆栈)。如果您正在根据BroadCastReceiver的输入更新UI,则应该检查是否存在这种情况。

我在两个单独的模块中有相同的.xml文件,其中有相同的视图id。

应用程序/ src / main / res / / header.xml布局 supportModule / src / main / res / layout / header.xml

两个布局都有相同的TextView id @+id/tv_prompt。

我的TextView tvPrompt = findViewById(R.id.tv_prompt);总是返回null。为了解决这个问题,我不得不将另一个xml文件重命名为header_main.xml。

在我的例子中,当我将调用从父对象移动到由父对象实例化的适配器对象时,findViewById返回null。在尝试了这里列出的技巧但没有成功之后,我将findViewById移回父对象中,并在适配器对象实例化期间将结果作为参数传递。 例如,我在父对象中这样做:

 Spinner hdSpinner = (Spinner)view.findViewById(R.id.accountsSpinner);

然后我在创建适配器对象时将hdSpinner作为参数传递:

  mTransactionAdapter = new TransactionAdapter(getActivity(),
        R.layout.transactions_list_item, null, from, to, 0, hdSpinner);

如果你在Fragment中,findViewById也可以返回null。如上所述:在Fragment中找到viewbyid

你应该调用getView()来返回Fragment中最顶层的View。然后你可以找到布局项(按钮,文本视图等)