Skip to content

Instantly share code, notes, and snippets.

@nseidm1
Last active August 29, 2015 13:56
Show Gist options
  • Save nseidm1/9327674 to your computer and use it in GitHub Desktop.
Save nseidm1/9327674 to your computer and use it in GitHub Desktop.
Overriden activity capable of inflating child fragment tags in fragment xml layouts. This activity will successfully use the ChildFragmentManager of the parent fragment. At the bottom of the gist is a custom attr definition. For your child fragment defined in xml you'll be definining the parent fragment name.
package com.project.floatingvideos;
import java.util.Random;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.widget.FrameLayout;
public abstract class ChildFragmentActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(final View parent, String name, final Context context, final AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.fragment);
final String parentFragmentName = a.getString(R.styleable.fragment_parent);
a.recycle();
if ("fragment".equals(name) && parentFragmentName != null) {
// Ensure a unique container id
final int containerId = getUniqueContainerId();
final String fragmentClass = attrs.getAttributeValue(null, "class");
// Add a container for the child fragment to the layout
//When that layout is attached add a child fragment to it using the ChildFragmentManager
//of the parent fragment specified by the parent attribute
final FrameLayout container = new FrameLayout(context);
Log.d(ChildFragmentActivity.class.getSimpleName(), "Child fragment to be inflated pending container attachment to window: " + fragmentClass);
container.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override public void onViewDetachedFromWindow(View v) {}
@Override
public void onViewAttachedToWindow(View v) {
Log.d(ChildFragmentActivity.class.getSimpleName(), "Container attached to window, inflating fragment: " + fragmentClass);
container.removeOnAttachStateChangeListener(this);
try {
Fragment parentFragment = getFragmentManager().findFragmentByTag(parentFragmentName);
if (parentFragment == null)
throw new IllegalStateException("Parent fragment unavailable");
Fragment childFragment = Fragment.instantiate(context, fragmentClass);
FragmentManager fragmentManager = parentFragment.getChildFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(containerId, childFragment, fragmentClass);
fragmentTransaction.commitAllowingStateLoss();
} catch(IllegalStateException e) {
e.printStackTrace();
}
}
});
container.setId(containerId);
return container;
} else if (!"fragment".equals(name)) {
return onCreateView(name, context, attrs);
} else {
Log.d(ChildFragmentActivity.class.getSimpleName(), "Parent fragment being loaded");
return super.onCreateView(parent, name, context, attrs);
}
}
private int getUniqueContainerId() {
int containerId;
do {
containerId = new Random().nextInt(1000);
} while (findViewById(containerId) != null);
return containerId;
}
@Override
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
Log.d(ChildFragmentActivity.class.getSimpleName(), "Parent Fragment Attached: " + fragment.getClass().getName());
}
}
//You need your custom attribute
// <declare-styleable name="fragment">
// <attr name="parent" format="string"/>
// </declare-styleable>
//Use the attribute on your intended child fragment
//app:parent="com.paltalk.chat.room.fragments.RoomDetailsFragment"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment