package cn.mutils.app.ui.core; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.animation.AnimationUtils; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.Toast; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import cn.mutils.app.event.listener.OnActivityResultListener; import cn.mutils.app.event.listener.OnClickListener; import cn.mutils.app.os.IContextProvider; import cn.mutils.app.ui.InfoToast; import cn.mutils.core.ILockable; import cn.mutils.core.annotation.event.Click; import cn.mutils.core.annotation.res.FindViewById; import cn.mutils.core.annotation.res.GetColor; import cn.mutils.core.annotation.res.GetColorStateList; import cn.mutils.core.annotation.res.GetDimension; import cn.mutils.core.annotation.res.GetDimensionPixelSize; import cn.mutils.core.annotation.res.GetDrawable; import cn.mutils.core.annotation.res.GetString; import cn.mutils.core.annotation.res.GetStringArray; import cn.mutils.core.annotation.res.LoadAnimation; import cn.mutils.core.annotation.res.SetContentView; import cn.mutils.core.reflect.ReflectUtil; import cn.mutils.core.task.IStoppable; import cn.mutils.core.task.IStoppableManager; /** * UI core implementation of framework */ @SuppressWarnings({"deprecation", "unchecked", "UnnecessaryLocalVariable", "SimplifiableIfStatement"}) public class UICore { /** * Hide keyboard when touch view who is not EditText and not focused */ public static void dispatchTouchEvent(MotionEvent ev, IWindowProvider dispatcher) { if (ev.getAction() != MotionEvent.ACTION_DOWN) { return; } boolean isSoftInputValid = false; Window w = dispatcher.getWindow(); View focus = w.getCurrentFocus(); if (focus != null && (focus instanceof EditText)) { EditText edit = (EditText) focus; int[] l = new int[2]; edit.getLocationInWindow(l); boolean touchEdit = (ev.getX() >= l[0]) && (ev.getX() <= l[0] + edit.getWidth()) && (ev.getY() >= l[1]) && (ev.getY() <= l[1] + edit.getHeight()); isSoftInputValid = touchEdit; } if (!isSoftInputValid) { InputMethodManager imm = (InputMethodManager) dispatcher.getContext() .getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isActive()) { imm.hideSoftInputFromWindow(focus != null ? focus.getWindowToken() : w.getDecorView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } } /** * Get content view */ public static View getContentView(IViewFinder finder) { View v = null; if (finder instanceof Activity) { v = ((Activity) finder).findViewById(android.R.id.content); } else if (finder instanceof Dialog) { v = ((Dialog) finder).findViewById(android.R.id.content); } else { if (finder instanceof View) { return (View) finder; } } if (v == null) { return null; } if (v instanceof ViewGroup) { ViewGroup vg = (ViewGroup) v; if (vg.getChildCount() > 0) { v = vg.getChildAt(0); } } return v; } /** * IOC for content view */ public static void injectContentView(IContentViewOwner owner) { Class<?> c = owner.getClass(); while (IContentViewOwner.class.isAssignableFrom(c)) { SetContentView s = c.getAnnotation(SetContentView.class); if (s != null) { owner.setContentView(s.value()); return; } c = c.getSuperclass(); } } /** * IOC for events */ public static void injectEvents(IViewFinder finder) { Class<?> c = finder.getClass(); while (IViewFinder.class.isAssignableFrom(c)) { for (Method m : c.getDeclaredMethods()) { Click oc = m.getAnnotation(Click.class); if (oc == null) { continue; } if (oc.value().length == 0 && (finder instanceof View)) { OnClickListener ocl = new OnClickListener(); ocl.setCallBack(m); ocl.setProxy(finder); ((View) finder).setOnClickListener(ocl); continue; } for (int id : oc.value()) { View v = findViewById(finder, id, View.class); if (v == null) { continue; } OnClickListener ocl = new OnClickListener(); ocl.setCallBack(m); ocl.setProxy(finder); v.setOnClickListener(ocl); } } c = c.getSuperclass(); } } /** * IOC for resources */ public static void injectResources(IViewFinder finder) { Context context = (finder instanceof IContextProvider) ? ((IContextProvider) finder).getContext() : null; Resources res = context == null ? null : context.getResources(); Class<?> c = finder.getClass(); while (IViewFinder.class.isAssignableFrom(c)) { for (Field f : c.getDeclaredFields()) { FindViewById fvbi = f.getAnnotation(FindViewById.class); if (fvbi != null) { View v = findViewById(finder, fvbi.value(), (Class<View>) f.getType()); if (v != null) { ReflectUtil.set(finder, f, v); } } if (context == null) { continue; } LoadAnimation la = f.getAnnotation(LoadAnimation.class); if (la != null) { ReflectUtil.set(finder, f, AnimationUtils.loadAnimation(context, la.value())); } if (res == null) { continue; } GetColor gc = f.getAnnotation(GetColor.class); if (gc != null) { ReflectUtil.set(finder, f, res.getColor(gc.value())); } GetColorStateList gcsl = f.getAnnotation(GetColorStateList.class); if (gcsl != null) { ReflectUtil.set(finder, f, res.getColorStateList(gcsl.value())); } GetDimension gd = f.getAnnotation(GetDimension.class); if (gd != null) { ReflectUtil.set(finder, f, res.getDimension(gd.value())); } GetDimensionPixelSize gdps = f.getAnnotation(GetDimensionPixelSize.class); if (gdps != null) { ReflectUtil.set(finder, f, res.getDimensionPixelSize(gdps.value())); } GetDrawable d = f.getAnnotation(GetDrawable.class); if (d != null) { ReflectUtil.set(finder, f, res.getDrawable(d.value())); } GetString gs = f.getAnnotation(GetString.class); if (gs != null) { ReflectUtil.set(finder, f, res.getString(gs.value())); } GetStringArray gsa = f.getAnnotation(GetStringArray.class); if (gsa != null) { ReflectUtil.set(finder, f, res.getStringArray(gsa.value())); } } c = c.getSuperclass(); } } public static <T extends View> T findViewById(Object root, int id, Class<T> viewClass) { if (root == null) { return null; } View view = null; if (root instanceof View) { view = (View) root; if (view.getId() == id) { if (viewClass != null) { if (viewClass.isInstance(view)) { return (T) view; } else { return null; } } return (T) view; } view = ((View) root).findViewById(id); } else if (root instanceof Activity) { view = ((Activity) root).findViewById(id); } else if (root instanceof Dialog) { view = ((Dialog) root).findViewById(id); } else if (root instanceof IView) { view = ((IView) root).toView().findViewById(id); } if (view != null) { if (viewClass != null) { if (viewClass.isInstance(view)) { return (T) view; } else { return null; } } return (T) view; } List<IStateView> bindViews = null; if (root instanceof IStateViewManager) { bindViews = ((IStateViewManager) root).getBindStateViews(); } if (bindViews != null) { for (IStateView stateView : bindViews) { T v = stateView.findViewById(id, viewClass); if (v != null) { return v; } } } List<View> cachedViews = null; if (root instanceof ICachedViewManager) { cachedViews = ((ICachedViewManager) root).getCachedViews(); } if (cachedViews != null) { for (View cacheView : cachedViews) { if (cacheView instanceof IStateView) { T v = ((IStateView) cacheView).findViewById(id, viewClass); if (v != null) { return v; } } else { View v = cacheView.findViewById(id); if (v != null) { if (viewClass != null) { if (viewClass.isInstance(v)) { return (T) v; } else { return null; } } return (T) v; } } } } return null; } public static void bindStateViews(IStateViewManager manager, View v) { bindStateViews(manager, v, 0, Integer.MAX_VALUE); } public static void bindStateViews(IStateViewManager manager, View v, int depth, int maxDepth) { if (depth >= maxDepth) { return; } if (v instanceof IStateView) { if (v != manager) { manager.bind((IStateView) v); return; } } if (v instanceof ViewGroup) { ViewGroup g = (ViewGroup) v; for (int i = 0, size = g.getChildCount(); i < size; i++) { bindStateViews(manager, g.getChildAt(i), depth + 1, maxDepth); } } } public static void bind(IStateViewManager manager, IStateView v) { List<IStateView> views = manager.getBindStateViews(); if (views.contains(v)) { return; } v.setManager(manager); views.add(v); } public static void bind(IStoppableManager manager, IStoppable s) { List<IStoppable> stopables = manager.getBindStoppables(); List<IStoppable> stopedList = null; for (IStoppable stopable : stopables) { if (stopable.equals(s)) { if (stopedList != null) { stopables.removeAll(stopedList); stopedList.clear(); } return; } if (stopable.isStopped()) { if (stopedList == null) { stopedList = new ArrayList<IStoppable>(); } stopedList.add(stopable); } } if (stopedList != null) { stopables.removeAll(stopedList); stopedList.clear(); } stopables.add(s); } public static void dispatchCreate(IStateView v) { if (v.isCreateDispatched()) { return; } v.onCreate(); v.setCreateDispatched(true); } public static void dispatchStart(IStateViewManager manager) { if (manager instanceof IStateView) { IStateView v = (IStateView) manager; if (!v.isCreateDispatched()) { dispatchCreate(v); } } if (manager.redirectToSelectedView()) { IStateView v = manager.getSelectedView(); if (v != null) { v.onStart(); } } else { List<IStateView> views = manager.getBindStateViews(); for (IStateView stateView : views) { stateView.onStart(); } } } public static void dispatchResume(IStateViewManager manager) { if (manager instanceof IStateView) { IStateView v = (IStateView) manager; if (!v.isCreateDispatched()) { v.onStart(); } } if (manager.redirectToSelectedView()) { IStateView v = manager.getSelectedView(); if (v != null) { v.onResume(); } } else { List<IStateView> views = manager.getBindStateViews(); for (IStateView stateView : views) { stateView.onResume(); } } } public static void dispatchPause(IStateViewManager manager) { if (manager instanceof IStateView) { IStateView v = (IStateView) manager; if (!v.isCreateDispatched()) { dispatchCreate(v); } } if (manager instanceof IStoppableManager) { ((IStoppableManager) manager).stopAll(); } if (manager.redirectToSelectedView()) { IStateView v = manager.getSelectedView(); if (v != null) { v.onPause(); } } else { List<IStateView> views = manager.getBindStateViews(); for (IStateView stateView : views) { stateView.onPause(); } } if (manager instanceof IToastOwner) { InfoToast toast = ((IToastOwner) manager).getInfoToast(); if (toast != null) { toast.hideNow(); } } } public static void dispatchStop(IStateViewManager manager) { if (manager instanceof IStateView) { IStateView v = (IStateView) manager; if (!v.isCreateDispatched()) { v.onPause(); } } if (manager.redirectToSelectedView()) { IStateView v = manager.getSelectedView(); if (v != null) { v.onStop(); } } else { List<IStateView> views = manager.getBindStateViews(); for (IStateView stateView : views) { stateView.onStop(); } } } public static void dispatchDestroy(IStateViewManager manager) { if (manager instanceof IStateView) { IStateView v = (IStateView) manager; if (!v.isCreateDispatched()) { return; } } if (manager instanceof IStoppableManager) { ((IStoppableManager) manager).stopAll(true); } List<IStateView> views = manager.getBindStateViews(); for (IStateView stateView : views) { stateView.onDestroy(); } views.clear(); } public static void stopAll(IStoppableManager manager) { stopAll(manager, false); } public static void stopAll(IStoppableManager manager, boolean includeLockable) { List<IStoppable> stopables = manager.getBindStoppables(); List<IStoppable> stopedList = null; for (IStoppable stopable : stopables) { if (!includeLockable) { if (stopable instanceof ILockable) { continue; } } stopable.stop(); if (stopedList == null) { stopedList = new ArrayList<IStoppable>(); } stopedList.add(stopable); } if (stopedList != null) { stopables.removeAll(stopedList); stopedList.clear(); } } public static boolean interceptBackPressed(IStateViewManager manager) { if (manager instanceof IStoppableManager) { List<IStoppable> stopables = ((IStoppableManager) manager).getBindStoppables(); boolean catchStopableed = false; List<IStoppable> stopedList = null; for (IStoppable stopable : stopables) { if (stopable instanceof ILockable) { continue; } if (stopable.isStopped()) { if (stopedList == null) { stopedList = new ArrayList<IStoppable>(); } stopedList.add(stopable); continue; } if (!stopable.isRunInBackground() && !stopable.isStopped()) { catchStopableed = true; stopable.stop(); if (stopedList == null) { stopedList = new ArrayList<IStoppable>(); } stopedList.add(stopable); } } if (stopedList != null) { stopables.removeAll(stopedList); stopedList.clear(); } if (catchStopableed) { return true; } } if (manager.redirectToSelectedView()) { IStateView v = manager.getSelectedView(); if (v != null) { if (v.onInterceptBackPressed()) { return true; } } } else { List<IStateView> views = manager.getBindStateViews(); for (IStateView stateView : views) { if (stateView.onInterceptBackPressed()) { return true; } } } return false; } public static void startActivity(IContextProvider provider, Intent intent) { provider.getContext().startActivity(intent); } public static void startActivityForResult(IActivityExecutor executor, Intent intent, int requestCode) { Context context = executor.getContext(); if (context instanceof Activity) { ((Activity) context).startActivityForResult(intent, requestCode); } } public static void onActivityResult(IActivityExecutor executor, int requestCode, int resultCode, Intent data) { Context context = executor.getContext(); List<OnActivityResultListener> listeners = executor.getOnActivityResultListeners(); if (listeners != null) { for (OnActivityResultListener listener : listeners) { listener.onActivityResult(context, requestCode, resultCode, data); } } if (!(executor instanceof IStateViewManager)) { return; } IStateViewManager manager = (IStateViewManager) executor; if (manager.redirectToSelectedView()) { IStateView selectedView = manager.getSelectedView(); if (selectedView == null) { return; } selectedView.onActivityResult(context, requestCode, resultCode, data); } else { List<IStateView> bindViews = manager.getBindStateViews(); if (bindViews == null) { return; } for (IStateView stateView : bindViews) { stateView.onActivityResult(context, requestCode, resultCode, data); } } } protected static boolean isEnabled(IToastOwner owner) { if (owner instanceof IActivity) { return ((IActivity) owner).isRunning(); } Context context = owner.getContext(); if (context instanceof IActivity) { return ((IActivity) context).isRunning(); } if (context instanceof Activity) { return !((Activity) context).isFinishing(); } return true; } public static void toast(IToastOwner owner, CharSequence s) { if (!isEnabled(owner)) { return; } Toast t = owner.getToast(); if (s == null) { t.cancel(); } else { if (s.equals("")) { t.cancel(); } else { t.setText(s); t.show(); } } } public static void toast(IToastOwner owner, int resId, Object... args) { if (!isEnabled(owner)) { return; } Toast t = owner.getToast(); if (resId == 0) { t.cancel(); } else { if (args != null && args.length != 0) { Context context = owner.getContext(); t.setText(context.getString(resId, args)); } else { t.setText(resId); } t.show(); } } }