findViewById不适合包含?

时间:2012-05-29 17:10:04

标签: android

我有一个包括:

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

include布局看起来像(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!");
}

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

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

所以我可以找到分配给include的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只是在运行时被剥离了元素吗?

由于

9 个答案:

答案 0 :(得分:67)

尝试检索<include />,然后在

中搜索

确保您的root与包含的XML文件中的根元素具有相同的ID .. ex

<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!");
}

答案 1 :(得分:11)

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

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

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

答案 2 :(得分:0)

你可以尝试找到外部父级(让我们称之为'op'),然后尝试op.findViewById()吗?

答案 3 :(得分:0)

我遇到了同样的问题。我发现我使用了具有相同名称的错误函数,其中包含以下两个参数:

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
    }

答案 4 :(得分:0)

未来的研究人员:https://stackoverflow.com/a/1760010/2790016 当您添加ID时,它会覆盖“实际布局”中外部标签的ID

鉴于大多数约束布局都需要一个ID来定位项目,因此从包含中删除该ID不是一个理想的答案。

答案 5 :(得分:0)

如果您为include元素指定了ID,并且在包含的布局中只有一个视图(在任何ViewGroup中都没有),在我的情况下为AdView,请使用include元素的ID,而不是包含的视图。

<?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元素,则可以使用视图id。同样,如果您的view位于ViewGroup之类的任何FrameLayout内,则可以使用视图id

答案 6 :(得分:0)

就我而言,inisialisasi您的包含必须与您的根视图包含相同。

包括:

interface ISkill
{
    void apply();
}

class Base : ISkill
{
    protected string name { get; set; }
    protected Base(string name)
    {
        this.name = name;
    }
    public void apply()
    {
        show();
        Console.WriteLine(name + " apply");
    }

    private void show()
    {
        Console.WriteLine("show:"+name);
    }
}

class Skill1 : Base
{
    public Skill1(): base("skill1"){}    
}
class Skill2 : Base
{
    public Skill2(): base("skill2"){}    
}

视图中包括:

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

活动中:

  <?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替换根视图中包含的包含ID

答案 7 :(得分:0)

我找到了解决这个问题的方法。

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

我使用合并来解决问题。

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

和在layout_stories中

<merge>
<LinearLayout
android:id="@+id/llItem">
 ...
</LinearLayout>
<merge>

答案 8 :(得分: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>