Mike T
Mike T

Reputation: 4787

Duplicate layout IDs returning as -1 after view replacement

Short Story: I have a layout "layout.xml", which gets replaced by another layout "success.xml" after a successful web request. Both layouts have an ImageView that provides the backgrounds to the layouts. These 2 backgrounds both need to be the same, and both are dependent on a user preference.

Longer Story: This all happens in a Fragmnet with an AsyncTask replacing the contentView with "success.xml" in onPostExecute after the web request. This happens as follows:

View view = getView();
view = null;
view = View.inflate(context, R.layout.success, null);

What I tried to do is give both ImageViews the following android:id="@+id/background_image" and then call

ImageView background = (ImageView)view.findViewById(R.id.background_image);
background.setImageResource(R.drawable.bg1);

This background-setting works for the initial view (layout.xml), but on trying to change to "success.xml", I get a NullPointException because background is null.

I've checked and the View's id is set to -1 while the original view's background_image id is set to something sensible and valid.

I've also tried setting the second view's background id like this: android:id="@id/background_image", i.e. without the '+', but still no luck.

The added complication is that it's not just 2 layouts, but about 5 that I need to do this for, so it would be really handy to recycle view id's.

Any help would be greatly appreciated.

Upvotes: 2

Views: 156

Answers (1)

user
user

Reputation: 87064

Your code for replacing the fragment's view will not do what you want, the original view will remain the same as you change only a reference to that view and not the actual object.

To replace the view of the fragment with the new layout you could have another ViewGroup(for example a FrameLayout) in the basic layout (layout.xml) wrapping your current content(don't forget to give it an id) of layouts.xml(as I understand this is the basic layout). Then, when it's time to replace the layout you could simply do:

// remove the current content
((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)).removeAllViews();
// add the new content
View.inflate(context, R.layout.success, ((ViewGroup) getView().findViewById(R.id.yourWrapperLayout)));

You could avoid adding an extra layout if, by any chance, all your five layouts have the same type for the root view(like a LinearLayout etc). In this case you would use the same code as above but you'll modify the other layouts file to use a merge tag. Also, you'll be looking for the id of the root in the layout.xml layout into which you'll add the content of the other files.

Then you could have the same ids, but you'll have to reinitialize any reference to the views(meaning that you'll have to search for the view again if you store a reference to the view(like a Button field in the fragment class)).

Upvotes: 2

Related Questions