56

我有一个包括:

<include
    android:id="@+id/placeHolder"
    layout="@layout/test" />

包含布局看起来像(test.xml):

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/outer"
    ... >

    <ImageView
        android:id="@+id/inner"
        ... />
</FrameLayout>

我似乎无法在运行时找到 id="inner" 的内部 ImageView:

ImageView iv = (ImageView)findViewById(R.id.inner);
if (iv == null) {
    Log.e(TAG, "Not found!");
}

我应该能够找到它吗?似乎因为它使用了“包含”,所以普通的 findViewById 方法不起作用。

- - - - - 更新 - - - - - - - -

所以我可以找到分配给包含的 id:

View view = findViewById(R.id.placeHolder); // ok

但我无法通过 id 找到它的任何孩子,例如:

view.findViewById(R.id.outer); // nope
view.findViewById(R.id.inner); // nope

如果我尝试直接搜索它们,则与原始版本相同,例如:

findViewById(R.id.outer); // nope
findViewById(R.id.inner); // nope

ids 可能只是在运行时从元素中剥离出来吗?

谢谢

4

9 回答 9

94

尝试检索<include />然后在其中搜索

确保您的根与包含的 XML 文件中的根元素具有相同的 ID。例如

<include
    android:id="@+id/outer"
    layout="@layout/test" />

然后使用以下方法检索您的“内部”内容:

FrameLayout outer = (FrameLayout)findViewById(R.id.outer);

ImageView iv = (ImageView)outer.findViewById(R.id.inner);
if (iv == null) {
    Log.e(TAG, "Not found!");
}
于 2012-05-29T17:15:16.913 回答
18

我只是想为未来的 Google 员工添加这一点,我遇到了相反的问题,其中包含的 xml(在本例中为外部)的根布局在调用 findViewById() 时为空,但外部的子级不为空。

include通过删除“视图”(在本例中为 placeHolder)的 id 属性为我解决了这个问题。当它消失时,我可以找到外部但它是 id :)

如果您需要为该项目分配一个 id include,我认为最好将其包装在另一个视图组中。

于 2015-03-03T15:21:57.580 回答
1

不要给你包含的布局一个 ID

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/twitterItem"
    android:id="@+id/item1">

    <include
        layout="@layout/item_common_layout"/>

</FrameLayout>

item_common_layout

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    ... >

    <ImageView
        android:id="@+id/inner"
        ... />
</FrameLayout>

现在您可以找到内部视图:

ImageView iv = (ImageView) view.findViewById(R.id.inner); // works fine!
于 2021-11-05T16:45:07.273 回答
0

您可以尝试然后找到外部parent(让我们称之为op)然后尝试op.findViewById()吗?

于 2012-05-29T17:14:25.107 回答
0

如果您已将 id 分配给include元素,并且在包含的布局中只有一个视图(没有任何ViewGroup),那么在我的情况下AdView,请使用元素的 idinclude而不是包含的视图。

<?xml version="1.0" encoding="utf-8"?>
<!--adview.xml-->
<com.google.android.gms.ads.AdView
        xmlns:ads="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/adView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        ads:adSize="BANNER"
        ads:adUnitId="@string/admob_banner_id">
</com.google.android.gms.ads.AdView>

activity_main.xml

<include
        layout="@layout/adview"
        android:id="@+id/adsLayout"
  />

活动中

AdView nullAdView=findViewById(R.id.adView); //this will give null
AdView adView = findViewById(R.id.adsLayout);  //this will be AdView

如果您不给id元素include,则可以使用 view id。此外,如果您view在任何ViewGroup类似的内部FrameLayout,则可以使用 view id

于 2019-01-22T08:06:25.053 回答
0

我有同样的问题。我发现我使用了一个错误的具有相同名称的函数和 2 个参数,如下所示:

public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
    super.onCreate(savedInstanceState, persistentState);
    setContentView(R.layout.activity_ble_connecting);
    //findViewByid() => wrong
} 

只有一个参数的正确函数:

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ble_connecting);
        //findViewByid() => correct
    }
于 2017-07-28T07:47:55.560 回答
0

未来的研究人员:https ://stackoverflow.com/a/1760010/2790016 当你添加一个 id 时,它会覆盖来自“真实布局”的外部标签的 id

鉴于大多数约束布局需要一个 id 来定位项目,从 include 中删除 id 并不是一个理想的答案。

于 2018-12-07T22:11:10.273 回答
0

我找到了这个问题的答案。

当我们同时设置 Incloud ID 和第一个内层时,就会出现这个问题。

我使用合并来解决问题。

 <include
    android:id="@+id/layout_stories"
    layout="@layout/layout_stories" />

在 layout_stories 中

<merge>
<LinearLayout
android:id="@+id/llItem">
 ...
</LinearLayout>
<merge>
于 2020-10-30T09:58:01.173 回答
0

我按照Daniel Wilson的回答得到了解决方案。我在同一个屏幕上多次使用相同的布局,并想使用不同的 id 来引用它们。因此,我没有将 id 分配给 include 标记,而是将它们简单地包装在另一个 viewGroup 中(我使用了 FrameLayout)并标识了 frameLayout 以访问内部子项。那成功了。例子:

在我的 main.xml 中:

<!--    ITEM 1-->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/twitterItem"
    android:id="@+id/item1">

    <include
        layout="@layout/item_common_layout"/>

</FrameLayout>

<!--    ITEM 2-->
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/item1"
    android:id="@+id/item2">

    <include
        layout="@layout/item_common_layout"/>

</FrameLayout>
于 2021-03-15T04:49:53.917 回答