Java tutorial
/* * Copyright (c) 2013 Cangol * <p> * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package mobi.cangol.mobile.base; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.content.res.TypedArray; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.support.annotation.AttrRes; import android.support.annotation.ColorInt; import android.support.v4.app.Fragment; import android.util.TypedValue; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import java.lang.ref.WeakReference; import mobi.cangol.mobile.CoreApplication; import mobi.cangol.mobile.logging.Log; import mobi.cangol.mobile.service.AppService; import mobi.cangol.mobile.service.session.SessionService; public abstract class BaseFragment extends Fragment { public static final int RESULT_CANCELED = 0; public static final int RESULT_OK = -1; protected final String TAG = Log.makeLogTag(this.getClass()); protected CoreApplication app; private long startTime; private int resultCode = RESULT_CANCELED; private Bundle resultData; private CustomFragmentManager stack; private InternalHandler handler; protected HandlerThread handlerThread; /** * view * * @param view */ abstract protected void findViews(View view); /** * ?view * * @param savedInstanceState */ abstract protected void initViews(Bundle savedInstanceState); /** * ?? * * @param savedInstanceState */ abstract protected void initData(Bundle savedInstanceState); /** * fragment * * @return */ protected FragmentInfo getNavigtionUpToFragment() { return null; } /** * ??fragment? * * @param containerId */ protected void initFragmentStack(int containerId) { if (null == stack) stack = CustomFragmentManager.forContainer(this.getActivity(), containerId, this.getChildFragmentManager()); } /** * ??fragment? * * @return */ final public CustomFragmentManager getCustomFragmentManager() { return stack; } /** * ?fragment???? * * @return */ public boolean isSingleton() { return false; } /** * ?,fragmenttrue,fragmentfalse * * @return */ public boolean isCleanStack() { return false; } /** * ?AppService * * @param name * @return */ public AppService getAppService(String name) { return app.getAppService(name); } /** * ?Session * * @return */ public SessionService getSession() { return app.getSession(); } @Override public void onAttach(Activity activity) { super.onAttach(activity); Log.v(TAG, "onAttach"); } @Override public void onAttachFragment(Fragment childFragment) { super.onAttachFragment(childFragment); Log.v(TAG, "onAttachFragment"); } @Override public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) { Log.v(TAG, "onCreateAnimation"); return super.onCreateAnimation(transit, enter, nextAnim); } @Override public void onMultiWindowModeChanged(boolean isInMultiWindowMode) { super.onMultiWindowModeChanged(isInMultiWindowMode); Log.v(TAG, "onMultiWindowModeChanged"); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.v(TAG, "onCreate"); handlerThread = new HandlerThread(TAG); handlerThread.start(); handler = new InternalHandler(this, handlerThread.getLooper()); app = (CoreApplication) this.getActivity().getApplication(); if (savedInstanceState == null) { } else { if (null != stack) stack.restoreState(savedInstanceState); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { { Log.v(TAG, "onCreateView"); startTime = System.currentTimeMillis(); } return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Log.v(TAG, "onViewCreated"); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Log.v(TAG, "onActivityCreated"); } @Override public void onPause() { super.onPause(); Log.v(TAG, "onPause"); } @Override public void onResume() { super.onResume(); Log.v(TAG, "onResume " + getIdleTime() + "s"); } @Override public void onStart() { super.onStart(); Log.v(TAG, "onStart"); } @Override public void onStop() { super.onStop(); Log.v(TAG, "onStop"); } @Override public void onDetach() { super.onDetach(); Log.v(TAG, "onDetach"); } @Override public void onDestroyView() { super.onDestroyView(); Log.v(TAG, "onDestroyView " + getIdleTime() + "s"); } @Override public void onDestroy() { getHandler().getLooper().quit(); handlerThread.quit(); if (null != stack) stack.destroy(); super.onDestroy(); Log.v(TAG, "onDestroy"); } public void onDrawerSlide(float slideOffset) { Log.v(TAG, "onDrawerSlide"); } public void onDrawerOpened() { Log.v(TAG, "onDrawerOpened"); } public void onDrawerClosed() { Log.v(TAG, "onDrawerClosed"); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (null != stack) stack.saveState(outState); Log.v(TAG, "onSaveInstanceState"); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.v(TAG, "onConfigurationChanged"); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.v(TAG, "onActivityResult"); } @Override public void onHiddenChanged(boolean hidden) { super.onHiddenChanged(hidden); Log.v(TAG, "onHiddenChanged " + hidden); } @Override public void onLowMemory() { super.onLowMemory(); Log.v(TAG, "onLowMemory"); } @Override public void onViewStateRestored(Bundle savedInstanceState) { super.onViewStateRestored(savedInstanceState); Log.v(TAG, "onViewStateRestored"); } /** * fragment * * @param requestCode * @param resultCode * @param data */ public void onFragmentResult(int requestCode, int resultCode, Bundle data) { Log.v(TAG, "onFragmentResult"); } /** * ?? * * @param resultCode */ final public void setResult(int resultCode) { this.setResult(resultCode, null); } /** * ??? * * @param resultCode * @param resultData */ final public void setResult(int resultCode, Bundle resultData) { this.resultCode = resultCode; this.resultData = resultData; } /** * */ final public void notifyResult() { BaseFragment target = (BaseFragment) getTargetFragment(); if (target != null) { target.onFragmentResult(getTargetRequestCode(), resultCode, resultData); } else { throw new IllegalStateException("Target Fragment is null"); } } /** * ? * * @return */ public boolean onSupportNavigateUp() { hideSoftInput(); return false; } /** * back * * @return */ public boolean onBackPressed() { if (null == stack) return false; if (stack.size() <= 1 || stack.peek() == null) { return false; } else { if (stack.peek().onBackPressed()) { return true; } else { stack.popBackStack(); return true; } } } /** * view * * @param id * @return */ public final View findViewById(int id) { if (getView() == null) return null; else return this.getView().findViewById(id); } /** * toast * * @param resId */ public void showToast(int resId) { if (isEnable()) { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); bfActivity.showToast(resId); } else { Log.e("IllegalStateException Fragment isEnable=false"); } } /** * toast * * @param resId * @param duration */ public void showToast(int resId, int duration) { if (isEnable()) { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); bfActivity.showToast(resId, duration); } else { Log.e("IllegalStateException Fragment isEnable=false"); } } /** * toast * * @param str */ public void showToast(String str) { if (isEnable()) { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); bfActivity.showToast(str); } else { Log.e("IllegalStateException Fragment isEnable=false"); } } /** * toast * * @param str * @param duration */ public void showToast(String str, int duration) { if (isEnable()) { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); bfActivity.showToast(str); } else { Log.e("IllegalStateException Fragment isEnable=false"); } } /** * ?fragment? * * @return */ public boolean isEnable() { if (null == getActivity() || !isAdded() || isRemoving() || isDetached()) { return false; } return true; } public void showSoftInput(EditText editText) { if (isEnable()) { BaseActivityDelegate bfActivity = (BaseActivityDelegate) this.getActivity(); bfActivity.showSoftInput(editText); } else { Log.e("IllegalStateException Fragment isEnable=false"); } } public void hideSoftInput() { if (isEnable()) { BaseActivityDelegate bfActivity = (BaseActivityDelegate) this.getActivity(); bfActivity.hideSoftInput(); } else { Log.e("IllegalStateException Fragment isEnable=false"); } } /** * ? * * @return */ public float getIdleTime() { return (System.currentTimeMillis() - startTime) / 1000.0f; } /** * ?? * * @return */ protected int getResultCode() { return resultCode; } /** * ?fragment * * @param fragmentClass */ final public void replaceFragment(Class<? extends BaseFragment> fragmentClass) { replaceFragment(fragmentClass, fragmentClass.getSimpleName(), null); } /** * ?fragment * * @param fragmentClass * @param args */ final public void replaceFragment(Class<? extends BaseFragment> fragmentClass, Bundle args) { replaceFragment(fragmentClass, fragmentClass.getSimpleName(), args); } /** * ?fragment * * @param fragmentClass * @param tag * @param args */ final public void replaceFragment(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args) { this.replaceFragment(fragmentClass, tag, args, null); } /** * ?fragment,? * * @param fragmentClass * @param tag * @param args * @param args */ final public void replaceFragmentForResult(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args, int requestCode) { if (requestCode != -1) { this.replaceFragment(fragmentClass, tag, args, new CustomFragmentTransaction().setTargetFragment(this, requestCode)); } else { throw new IllegalStateException("requestCode!=-1"); } } /** * ?fragment * * @param fragmentClass * @param tag * @param args * @param customFragmentTransaction */ final public void replaceFragment(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args, CustomFragmentTransaction customFragmentTransaction) { BaseFragment parent = (BaseFragment) this.getParentFragment(); CustomFragmentManager stack = null; if (parent != null) { stack = parent.getCustomFragmentManager(); } else { if (getActivity() == null) { throw new IllegalStateException("getActivity is null"); } else { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); stack = bfActivity.getCustomFragmentManager(); } } if (null != stack && !stack.isStateSaved()) { stack.replace(fragmentClass, tag, args, customFragmentTransaction); stack.commit(); } else { Log.e(TAG, "Can not perform this action after onSaveInstanceState"); } } /** * ?onSaveInstanceState * Support 26.0.0-alpha1 ??isStateSaved * ???mStateSaved * ??? * * @return */ public boolean isSavedState() { BaseFragment parent = (BaseFragment) this.getParentFragment(); CustomFragmentManager stack = null; if (parent != null) { stack = parent.getCustomFragmentManager(); } else { if (getActivity() == null) { return false; } else { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); stack = bfActivity.getCustomFragmentManager(); } } if (stack != null) { return stack.isStateSaved(); } else { return false; } } /** * ?fragment * * @param fragmentClass * @param tag * @param args */ final public void replaceParentFragment(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args) { replaceParentFragment(fragmentClass, tag, args, null); } /** * ?fragment,? * * @param fragmentClass * @param tag * @param args * @param requestCode */ final public void replaceParentFragmentForResult(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args, int requestCode) { if (requestCode != -1) { this.replaceParentFragment(fragmentClass, tag, args, new CustomFragmentTransaction().setTargetFragment(this, requestCode)); } else { throw new IllegalStateException("requestCode!=-1"); } } /** * ?fragment * * @param fragmentClass * @param tag * @param args * @param customFragmentTransaction */ final public void replaceParentFragment(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args, CustomFragmentTransaction customFragmentTransaction) { BaseFragment parent = (BaseFragment) this.getParentFragment(); if (parent != null) { parent.replaceFragment(fragmentClass, tag, args, customFragmentTransaction); } else { throw new IllegalStateException("ParentFragment is null"); } } /** * ??fragment * * @param fragmentClass * @param tag * @param args */ final public void replaceChildFragment(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args) { replaceChildFragment(fragmentClass, tag, args, null); } /** * ??fragment * * @param fragmentClass * @param tag * @param args * @param customFragmentTransaction */ final public void replaceChildFragment(Class<? extends BaseFragment> fragmentClass, String tag, Bundle args, CustomFragmentTransaction customFragmentTransaction) { if (stack != null) { if (!stack.isStateSaved()) { stack.replace(fragmentClass, tag, args, customFragmentTransaction); stack.commit(); } else { Log.e(TAG, "Can not perform this action after onSaveInstanceState"); } } else { throw new IllegalStateException("fragment'CustomFragmentManager is null, Please initFragmentStack"); } } /** * ?fragment */ final public void popBackStack() { BaseFragment parent = (BaseFragment) this.getParentFragment(); if (parent != null) { parent.getCustomFragmentManager().popBackStack(); } else { if (getActivity() == null) { throw new IllegalStateException("getActivity is null"); } else { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); bfActivity.getCustomFragmentManager().popBackStack(); } } } /** * fragment */ final public void popBackStackAll() { BaseFragment parent = (BaseFragment) this.getParentFragment(); if (parent != null) { parent.getCustomFragmentManager().popBackStackAll(); } else { if (getActivity() == null) { throw new IllegalStateException("getActivity is null"); } else { CustomFragmentActivityDelegate bfActivity = (CustomFragmentActivityDelegate) this.getActivity(); bfActivity.getCustomFragmentManager().popBackStackAll(); } } } protected Handler getHandler() { return handler; } protected void handleMessage(Message msg) { } protected void postRunnable(StaticInnerRunnable runnable) { if (handler != null && runnable != null) handler.post(runnable); } protected void postRunnable(Runnable runnable) { if (handler != null && runnable != null) handler.post(runnable); } public boolean onKeyUp(int keyCode, KeyEvent event) { if (null == stack || stack.size() == 0 || stack.peek() == null) { return false; } else { return stack.peek().onKeyUp(keyCode, event); } } public boolean onKeyDown(int keyCode, KeyEvent event) { if (null == stack || stack.size() == 0 || stack.peek() == null) { return false; } else { return stack.peek().onKeyDown(keyCode, event); } } protected static class StaticInnerRunnable implements Runnable { @Override public void run() { } } protected final static class InternalHandler extends Handler { private final WeakReference<BaseFragment> mFragmentRef; public InternalHandler(BaseFragment fragment, Looper looper) { super(looper); mFragmentRef = new WeakReference<>(fragment); } public void handleMessage(Message msg) { BaseFragment fragment = mFragmentRef.get(); if (fragment != null && fragment.isEnable()) { fragment.handleMessage(msg); } } } @ColorInt public int getThemeAttrColor(@AttrRes int colorAttr) { if (getActivity() == null) { throw new IllegalStateException("getActivity is null"); } else { TypedArray array = getActivity().obtainStyledAttributes(null, new int[] { colorAttr }); try { return array.getColor(0, 0); } finally { array.recycle(); } } } public TypedValue getAttrTypedValue(@AttrRes int attr) { if (getActivity() == null) { throw new IllegalStateException("getActivity is null"); } else { TypedValue typedValue = new TypedValue(); getActivity().getTheme().resolveAttribute(attr, typedValue, true); return typedValue; } } }