package cn.mutils.app.ui;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import cn.mutils.app.ui.core.IFragmenter;
import cn.mutils.app.ui.core.IFragmenterManager;
import cn.mutils.app.ui.core.IStateView;
import cn.mutils.app.ui.core.UICore;
@SuppressWarnings("unchecked")
public class Fragmenter extends StateView implements IFragmenter, IFragmenterManager {
protected FragmentManager mSupportFragmentManagerFromParent;
protected FragmentWrapper mFragment;
protected View mContentView;
protected boolean mFragmentVisible = false;
protected boolean mLocked;
public Fragmenter(Context context) {
super(context);
}
public Fragmenter(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Fragmenter(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
protected void checkValidId() {
if (this.getId() == View.NO_ID) {
throw new UnsupportedOperationException("Fragmenter must has id");
}
}
@Override
public void setLocked(boolean locked) {
mLocked = locked;
}
@Override
public boolean isLocked() {
return mLocked;
}
@Override
public boolean isFragmentVisible() {
return mFragmentVisible;
}
@Override
public void setFragmentVisible(boolean visible) {
if (mLocked) {
return;
}
if (mFragmentVisible == visible) {
return;
}
FragmentManager fm = this.getSupportFragmentManagerFromParent();
FragmentTransaction ft = fm.beginTransaction();
if (visible) {
ft.show(mFragment);
} else {
ft.hide(mFragment);
}
ft.commitAllowingStateLoss();
mFragmentVisible = visible;
}
@Override
public void onStart() {
super.onStart();
setFragmentVisible(true);
}
@Override
public void onStop() {
setFragmentVisible(false);
super.onStop();
}
@Override
public void onDestroy() {
FragmentManager fm = this.getSupportFragmentManagerFromParent();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(mFragment);
ft.commitAllowingStateLoss();
super.onDestroy();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
if (this.getChildCount() != 0) {
throw new UnsupportedOperationException("Fragmenter must be empty in layout Resource");
}
}
public void setContentView(View v) {
if (mContentView != null || mFragment != null) {
throw new UnsupportedOperationException();
}
checkValidId();
mContentView = v;
bindStateViews();
mFragment = new FragmentWrapper();
mFragment.setContentView(mContentView);
FragmentManager fm = this.getSupportFragmentManagerFromParent();
FragmentTransaction ft = fm.beginTransaction();
ft.add(this.getId(), mFragment);
ft.hide(mFragment);
ft.commitAllowingStateLoss();
UICore.injectResources(this);
UICore.injectEvents(this);
}
@Override
public void setContentView(int layoutRes) {
LayoutInflater inflater = LayoutInflater.from(getContext());
setContentView(inflater.inflate(layoutRes, this, false));
}
@Override
protected void bindStateViews() {
if (mContentView == null) {
return;
}
UICore.bindStateViews(this, mContentView);
}
@Override
public <T extends View> T findViewById(int id, Class<T> viewClass) {
if (this.getId() == id) {
if (viewClass != null) {
if (viewClass.isInstance(this)) {
return (T) this;
} else {
return null;
}
}
return (T) this;
}
return UICore.findViewById(mContentView, id, viewClass);
}
@Override
public FragmentManager getSupportFragmentManager() {
return mFragment.getChildFragmentManager();
}
@Override
public FragmentManager getSupportFragmentManagerFromParent() {
if (mSupportFragmentManagerFromParent == null) {
Object o = this.getManager();
while (o != null) {
if (o instanceof IFragmenterManager) {
mSupportFragmentManagerFromParent = ((IFragmenterManager) o).getSupportFragmentManager();
}
if (o instanceof IStateView) {
o = ((IStateView) o).getManager();
} else {
break;
}
}
Context context = this.getContext();
if (context instanceof FragmentActivity) {
mSupportFragmentManagerFromParent = ((FragmentActivity) context).getSupportFragmentManager();
} else {
throw new UnsupportedOperationException();
}
}
return mSupportFragmentManagerFromParent;
}
public static class FragmentWrapper extends Fragment {
protected View mContentView;
public void setContentView(View contentView) {
mContentView = contentView;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mContentView == null) {
return new View(getActivity());// fix NullPointerException
}
return mContentView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
setUserVisibleHint(true);
outState.putString("FragmentWrapper", "onSaveInstanceState");
super.onSaveInstanceState(outState);
}
}
}