package com.reactnativenavigation.screens;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.FrameLayout;
import com.reactnativenavigation.R;
import com.reactnativenavigation.params.ScreenParams;
import com.reactnativenavigation.utils.ViewUtils;
import com.reactnativenavigation.views.ContentView;
import com.reactnativenavigation.views.LeftButtonOnClickListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@SuppressWarnings("ResourceType")
public class FragmentScreen extends Screen {
private static final String CONTRACT_GET_FRAGMENT = "getFragment";
private static final String CONTRACT_GET_SUPPORT_FRAGMENT = "getSupportFragment";
private FrameLayout content;
private ContentView contentView;
public FragmentScreen(AppCompatActivity activity, ScreenParams screenParams, LeftButtonOnClickListener leftButtonOnClickListener) {
super(activity, screenParams, leftButtonOnClickListener);
}
@Override
public ContentView getContentView() {
return contentView;
}
@Override
protected void createContent() {
content = new FrameLayout(getContext());
content.setId(R.id.fragment_screen_content);
addContent();
addFragment();
}
private void addContent() {
contentView = new ContentView(getContext(),
screenParams.screenId,
screenParams.navigationParams);
addView(contentView, 0, 0);
LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
if (screenParams.styleParams.drawScreenBelowTopBar) {
params.addRule(BELOW, topBar.getId());
}
addView(content, params);
}
private void addFragment() {
try {
Fragment fragment = tryGetFragment();
if (fragment != null) {
addFragment(fragment);
return;
}
android.support.v4.app.Fragment supportFragment = tryGetSupportFragment();
if (supportFragment != null) {
addSupportFragment(supportFragment);
return;
}
throw new RuntimeException("must provide public static method " + CONTRACT_GET_FRAGMENT + " or " + CONTRACT_GET_SUPPORT_FRAGMENT);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void addFragment(Fragment fragment) {
FragmentManager fm = activity.getFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.fragment_screen_content, fragment);
transaction.commitAllowingStateLoss();
}
private void addSupportFragment(android.support.v4.app.Fragment supportFragment) {
android.support.v4.app.FragmentManager fm = activity.getSupportFragmentManager();
android.support.v4.app.FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.fragment_screen_content, supportFragment);
transaction.commitAllowingStateLoss();
}
@Nullable
private Fragment tryGetFragment() throws ClassNotFoundException, IllegalAccessException, InvocationTargetException {
try {
String className = screenParams.fragmentCreatorClassName;
Class<?> fragmentCreatorClass = Class.forName(className);
Method method = fragmentCreatorClass.getMethod(CONTRACT_GET_FRAGMENT, Bundle.class);
return (android.app.Fragment) method.invoke(null, screenParams.fragmentCreatorPassProps);
} catch (NoSuchMethodException noSuchMethod) {
return null;
}
}
@Nullable
private android.support.v4.app.Fragment tryGetSupportFragment() throws ClassNotFoundException, IllegalAccessException, InvocationTargetException {
try {
String className = screenParams.fragmentCreatorClassName;
Class<?> fragmentCreatorClass = Class.forName(className);
Method method = fragmentCreatorClass.getMethod(CONTRACT_GET_SUPPORT_FRAGMENT, Bundle.class);
return (android.support.v4.app.Fragment) method.invoke(null, screenParams.fragmentCreatorPassProps);
} catch (NoSuchMethodException noSuchMethod) {
return null;
}
}
@Override
public void unmountReactView() {
contentView.unmountReactView();
}
@Override
public String getNavigatorEventId() {
return screenParams.getNavigatorEventId();
}
@Override
public void setOnDisplayListener(final OnDisplayListener onContentViewDisplayedListener) {
ViewUtils.runOnPreDraw(content, new Runnable() {
@Override
public void run() {
onContentViewDisplayedListener.onDisplay();
}
});
}
}