I have a complex "floating view" hierarchy that I am moving between different activities. As these views are shared across activities, they should all have a MutableContextWrapper
that will allow them to change the base context. In theory I can have multiple floating views simultaneously.
Here is an example XML for a floating view:
<com.test.views.SampleFloatingView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sample_floating_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.test.views.MinimizedImage
android:layout_width="90dp"
android:layout_height="90dp"
android:scaleType="center"/>
</com.test.views.SampleFloatingView>
I am inflating this XML using a MutableContextWrapper
and add it to a FrameLayout that will hold it (so I can drag it across the screen), but I'n not getting the result I need:
@NonNull
private FrameLayout createSampleFloatingView() {
MutableContextWrapper mutableContextWrapper = new MutableContextWrapper(getActivity());
final FrameLayout view = new FrameLayout(mutableContextWrapper);
LayoutInflater layoutInflater = LayoutInflater.from(mutableContextWrapper);
View floatingView = layoutInflater.inflate(R.layout.sample_floating_view, null, true).findViewById(R.id.sample_floating_view);
setViewMutableContext(floatingView);
view.addView(floatingView);
return view;
}
private void setViewMutableContext(View view) {
Context context = view.getContext();
if (context instanceof MutableContextWrapper) {
((MutableContextWrapper) context).setBaseContext(getActivity());
} else {
throw new RuntimeException("View " + view + " doesn't have a MutableContextWrapper");
}
if (view instanceof ViewGroup) {
int childCount = ((ViewGroup) view).getChildCount();
for (int i = 0; i < childCount; i++) {
setViewMutableContext(((ViewGroup) view).getChildAt(i));
}
}
}
The problem is that while the FrameLayout
has a MutableContextWrapper
the context of the inflated objects is the Activity which creates the view. This means that the code above crashes as SampleFloatingView
doesn't have a MutableContextWrapper
. If I remove this code a memory leak would later occur once I disconnect the view from the original activity and move it to the next.
An obvious solution to this issue would be to create the whole hierarchy manually and pass the MutableContextWrapper
in the constructor (like I do for the FrameLayout
), but I rather avoid it for obvious reasons.
My question is whether there is a better way that will allow me to inflate views from XML and force their context to point to a MutableContextWrapper
?