void SetPrivateFactoryInternal() { // Already tried to set the factory. if (setPrivateFactory) { return; } // Reflection (Or Old Device) skip. if (!CalligraphyConfig.Get().Reflection) { return; } // Skip if not attached to an activity. if (!(Context is IFactory2)) { setPrivateFactory = true; return; } Method setPrivateFactoryMethod = ReflectionUtils.GetMethod(Java.Lang.Class.FromType(typeof(LayoutInflater)), "setPrivateFactory"); if (setPrivateFactoryMethod != null) { ReflectionUtils.InvokeMethod(this, setPrivateFactoryMethod, new PrivateWrapperFactory2((IFactory2)Context, this, calligraphyFactory)); } setPrivateFactory = true; }
/// <summary> /// Nasty method to inflate custom layouts that haven't been handled else where. If this fails it /// will fall back through to the PhoneLayoutInflater method of inflating custom views where /// Calligraphy will NOT have a hook into. /// </summary> /// <returns>view or the View we inflate in here.</returns> /// <param name="parent">Parent view.</param> /// <param name="view">view if it has been inflated by this point, if this is not null this method just returns this value.</param> /// <param name="name">name of the thing to inflate.</param> /// <param name="viewContext">Context to inflate by if parent is null</param> /// <param name="attrs">Attr for this view which we can steal fontPath from too.</param> internal View CreateCustomViewInternal(View parent, View view, string name, Context viewContext, IAttributeSet attrs) { // I by no means advise anyone to do this normally, but Google have locked down access to // the createView() method, so we never get a callback with attributes at the end of the // createViewFromTag chain (which would solve all this unnecessary rubbish). // We at the very least try to optimise this as much as possible. // We only call for customViews (As they are the ones that never go through onCreateView(...)). // We also maintain the Field reference and make it accessible which will make a pretty // significant difference to performance on Android 4.0+. // If CustomViewCreation is off skip this. if (!CalligraphyConfig.Get().CustomViewCreation) { return(view); } if (view == null && name.IndexOf('.') > -1) { if (constructorArgs == null) { constructorArgs = ReflectionUtils.GetField(Java.Lang.Class.FromType(typeof(LayoutInflater)), "mConstructorArgs"); } Java.Lang.Object[] constructorArgsArr = (Java.Lang.Object[])ReflectionUtils.GetValue(constructorArgs, this); Java.Lang.Object lastContext = constructorArgsArr[0]; // The LayoutInflater actually finds out the correct context to use. We just need to set // it on the mConstructor for the internal method. // Set the constructor ars up for the createView, not sure why we can't pass these in. constructorArgsArr[0] = viewContext; ReflectionUtils.SetValue(constructorArgs, this, constructorArgsArr); try { view = CreateView(name, null, attrs); } catch (Java.Lang.ClassNotFoundException) { } finally { constructorArgsArr[0] = lastContext; ReflectionUtils.SetValue(constructorArgs, this, constructorArgsArr); } } return(view); }
/// <summary> /// Some styles are in sub styles, such as actionBarTextStyle etc.. /// </summary> /// <returns>2 element array, default to -1 unless a style has been found..</returns> /// <param name="view">View to check.</param> protected static int[] GetStyleForTextView(TextView view) { int[] styleIds = { -1, -1 }; // Try to find the specific actionbar styles if (IsActionBarTitle(view)) { styleIds[0] = Android.Resource.Attribute.ActionBarStyle; styleIds[1] = Android.Resource.Attribute.TitleTextStyle; } else if (IsActionBarSubTitle(view)) { styleIds[0] = Android.Resource.Attribute.ActionBarStyle; styleIds[1] = Android.Resource.Attribute.SubtitleTextStyle; } if (styleIds[0] == -1) { // Use TextAppearance as default style styleIds[0] = CalligraphyConfig.Get().ClassStyleAttributeMap.ContainsKey(view.GetType()) ? CalligraphyConfig.Get().ClassStyleAttributeMap[view.GetType()] : Android.Resource.Attribute.TextAppearance; } return(styleIds); }