findViewById not working for an include?
AndroidAndroid Problem Overview
I have an include like:
<include
android:id="@+id/placeHolder"
layout="@layout/test" />
The include layout looks like (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>
I can't seem to find the inner ImageView with id="inner" at runtime:
ImageView iv = (ImageView)findViewById(R.id.inner);
if (iv == null) {
Log.e(TAG, "Not found!");
}
Should I be able to find it? It seems like since it's using an "include", the normal findViewById method does not work.
---------- Update ----------------
So I can find the id assigned to the include:
View view = findViewById(R.id.placeHolder); // ok
but I can't find any of its children by id like:
view.findViewById(R.id.outer); // nope
view.findViewById(R.id.inner); // nope
same as the original if I try searching for them directly like:
findViewById(R.id.outer); // nope
findViewById(R.id.inner); // nope
Do ids just get stripped off of
Thanks
Android Solutions
Solution 1 - Android
Try retrieving the <include />
and then searching within that
Make sure your root
<include
android:id="@+id/outer"
layout="@layout/test" />
Then retrieve your "inner" content using:
FrameLayout outer = (FrameLayout)findViewById(R.id.outer);
ImageView iv = (ImageView)outer.findViewById(R.id.inner);
if (iv == null) {
Log.e(TAG, "Not found!");
}
Solution 2 - Android
I just wanted to add to this for future Googlers, I had kind of the opposite problem where the root layout of the included xml (in this case outer), was null when calling findViewById(), but the children of outer were not null.
The problem was solved for me by removing the id property of the include
'view' (in this case placeHolder). When that was gone, I could find outer but it's id :)
If you need a an id assigned to the include
item, I think it's better to wrap it in another viewgroup.
Solution 3 - Android
Don't give your included layout an 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>
now you could find inner Views:
ImageView iv = (ImageView) view.findViewById(R.id.inner); // works fine!
Solution 4 - Android
Can you try then finding the outer parent
(lets call it op
) and then try op.findViewById()
?
Solution 5 - Android
I had the same problem. I found out that I used a wrong function with the same name with 2 parameters as following:
public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
setContentView(R.layout.activity_ble_connecting);
//findViewByid() => wrong
}
correct function with only one parameters:
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ble_connecting);
//findViewByid() => correct
}
Solution 6 - Android
Future researchers: https://stackoverflow.com/a/1760010/2790016
when you add an id to
Given that most constraint layouts need an id to positions items, removing the id from include is not an ideal answer.
Solution 7 - Android
If you have given the id to the include
element and you have only single view in the included layout (not in any ViewGroup
), in my case AdView
, then use the id of include
element instead of included view.
<?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"
/>
In activity
AdView nullAdView=findViewById(R.id.adView); //this will give null
AdView adView = findViewById(R.id.adsLayout); //this will be AdView
If you do not give id
to include
element then it is ok to use view id
. Also if your view
is inside any ViewGroup
like FrameLayout
then it is ok to use view id
.
Solution 8 - Android
I found the answer to this problem.
This problem arises when we set both the Incloud ID and the first inner layer.
I used merge to solve the problem.
<include
android:id="@+id/layout_stories"
layout="@layout/layout_stories" />
and in layout_stories
<merge>
<LinearLayout
android:id="@+id/llItem">
...
</LinearLayout>
<merge>
Solution 9 - Android
I followed Daniel Wilson's answer and got the solution. I was using the same layout multiple times in same screen and wanted to refer them using different id. So, instead of assigning id to the include tag, I simply wrapped them in another viewGroup (I used FrameLayout) and id'ed the frameLayout to access the inner
In my 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>