From 7a4a2c0c8aa6e3032d55c9836a37c2de49e68c2a Mon Sep 17 00:00:00 2001 From: James Barr Date: Thu, 19 Jan 2017 23:53:42 -0800 Subject: [PATCH 1/3] Refactor Calligraphy into a ViewPump interceptor --- CalligraphySample/build.gradle | 1 + .../sample/CalligraphyApplication.java | 27 +- .../calligraphy/sample/MainActivity.java | 8 +- build.gradle | 1 + calligraphy/build.gradle | 1 + calligraphy/consumer-proguard-rules.txt | 4 +- calligraphy/gradle.properties | 2 +- calligraphy/src/main/AndroidManifest.xml | 2 +- .../CalligraphyActivityFactory.java | 34 -- .../CalligraphyContextWrapper.java | 118 ------- .../CalligraphyLayoutInflater.java | 311 ------------------ .../calligraphy/ReflectionUtils.java | 61 ---- .../CalligraphyConfig.java | 121 ++----- .../CalligraphyFactory.java | 34 +- .../calligraphy3/CalligraphyInterceptor.java | 22 ++ .../CalligraphyTypefaceSpan.java | 2 +- .../CalligraphyUtils.java | 4 +- .../co/chrisjenx/calligraphy3/FontMapper.java | 5 + .../HasTypeface.java | 4 +- .../TypefaceUtils.java | 2 +- 20 files changed, 106 insertions(+), 658 deletions(-) delete mode 100644 calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyActivityFactory.java delete mode 100644 calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java delete mode 100644 calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java delete mode 100644 calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/ReflectionUtils.java rename calligraphy/src/main/java/uk/co/chrisjenx/{calligraphy => calligraphy3}/CalligraphyConfig.java (64%) rename calligraphy/src/main/java/uk/co/chrisjenx/{calligraphy => calligraphy3}/CalligraphyFactory.java (88%) create mode 100644 calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java rename calligraphy/src/main/java/uk/co/chrisjenx/{calligraphy => calligraphy3}/CalligraphyTypefaceSpan.java (96%) rename calligraphy/src/main/java/uk/co/chrisjenx/{calligraphy => calligraphy3}/CalligraphyUtils.java (99%) create mode 100644 calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java rename calligraphy/src/main/java/uk/co/chrisjenx/{calligraphy => calligraphy3}/HasTypeface.java (81%) rename calligraphy/src/main/java/uk/co/chrisjenx/{calligraphy => calligraphy3}/TypefaceUtils.java (98%) diff --git a/CalligraphySample/build.gradle b/CalligraphySample/build.gradle index 3e10d6d..19f0133 100644 --- a/CalligraphySample/build.gradle +++ b/CalligraphySample/build.gradle @@ -24,6 +24,7 @@ android { dependencies { compile project(':calligraphy') + compile 'io.github.inflationx:viewpump:0.1.0-SNAPSHOT' compile 'com.android.support:support-v4:24.0.0' compile 'com.android.support:appcompat-v7:24.0.0' diff --git a/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java b/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java index 826a408..0a5405d 100644 --- a/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java +++ b/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java @@ -2,7 +2,10 @@ import android.app.Application; -import uk.co.chrisjenx.calligraphy.CalligraphyConfig; +import io.github.inflationx.viewpump.ViewPump; +import uk.co.chrisjenx.calligraphy3.CalligraphyConfig; +import uk.co.chrisjenx.calligraphy3.CalligraphyInterceptor; +import uk.co.chrisjenx.calligraphy3.FontMapper; /** * Created by chris on 06/05/2014. @@ -13,12 +16,20 @@ public class CalligraphyApplication extends Application { @Override public void onCreate() { super.onCreate(); - CalligraphyConfig.initDefault(new CalligraphyConfig.Builder() - .setDefaultFontPath("fonts/Roboto-ThinItalic.ttf") - .setFontAttrId(R.attr.fontPath) - .addCustomViewWithSetTypeface(CustomViewWithTypefaceSupport.class) - .addCustomStyle(TextField.class, R.attr.textFieldStyle) - .build() - ); + ViewPump.init(ViewPump.builder() + .addInterceptor(new CalligraphyInterceptor( + new CalligraphyConfig.Builder() + .setDefaultFontPath("fonts/Roboto-ThinItalic.ttf") + .setFontAttrId(R.attr.fontPath) + .setFontMapper(new FontMapper() { + @Override + public String map(String font) { + return font; + } + }) + .addCustomViewWithSetTypeface(CustomViewWithTypefaceSupport.class) + .addCustomStyle(TextField.class, R.attr.textFieldStyle) + .build())) + .build()); } } diff --git a/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/MainActivity.java b/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/MainActivity.java index 7131d30..ec99c5d 100644 --- a/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/MainActivity.java +++ b/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/MainActivity.java @@ -7,7 +7,7 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; -import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper; +import io.github.inflationx.viewpump.ViewPumpContextWrapper; import static butterknife.ButterKnife.findById; @@ -52,17 +52,17 @@ public void run() { } /* - Uncomment if you disable PrivateFactory injection. See CalligraphyConfig#disablePrivateFactoryInjection() + Uncomment if you disable PrivateFactory injection. See ViewPumpConfig#setPrivateFactoryInjectionEnabled(boolean) */ // @Override // @TargetApi(Build.VERSION_CODES.HONEYCOMB) // public View onCreateView(View parent, String name, @NonNull Context context, @NonNull AttributeSet attrs) { -// return CalligraphyContextWrapper.onActivityCreateView(this, parent, super.onCreateView(parent, name, context, attrs), name, context, attrs); +// return ViewPumpContextWrapper.onActivityCreateView(this, parent, super.onCreateView(parent, name, context, attrs), name, context, attrs); // } @Override protected void attachBaseContext(Context newBase) { - super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); + super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase)); } } diff --git a/build.gradle b/build.gradle index 8009b4c..5f70a94 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ buildscript { allprojects { repositories { + mavenLocal() jcenter() } // Is Release Build? diff --git a/calligraphy/build.gradle b/calligraphy/build.gradle index 0180f5d..ec5b5cf 100644 --- a/calligraphy/build.gradle +++ b/calligraphy/build.gradle @@ -21,6 +21,7 @@ android { } dependencies { + compile 'io.github.inflationx:viewpump:0.1.0-SNAPSHOT' compile 'com.android.support:appcompat-v7:24.0.0' } diff --git a/calligraphy/consumer-proguard-rules.txt b/calligraphy/consumer-proguard-rules.txt index 10691cb..5c6256a 100644 --- a/calligraphy/consumer-proguard-rules.txt +++ b/calligraphy/consumer-proguard-rules.txt @@ -16,6 +16,6 @@ # public *; #} --keep class uk.co.chrisjenx.calligraphy.* { *; } --keep class uk.co.chrisjenx.calligraphy.*$* { *; } +-keep class uk.co.chrisjenx.calligraphy3.* { *; } +-keep class uk.co.chrisjenx.calligraphy3.*$* { *; } diff --git a/calligraphy/gradle.properties b/calligraphy/gradle.properties index 9e72cf6..577ffbd 100644 --- a/calligraphy/gradle.properties +++ b/calligraphy/gradle.properties @@ -2,5 +2,5 @@ # See parent properties for global properties POM_NAME=Calligraphy -POM_ARTIFACT_ID=calligraphy +POM_ARTIFACT_ID=calligraphy3 POM_PACKAGING=aar \ No newline at end of file diff --git a/calligraphy/src/main/AndroidManifest.xml b/calligraphy/src/main/AndroidManifest.xml index 921769e..4773b40 100644 --- a/calligraphy/src/main/AndroidManifest.xml +++ b/calligraphy/src/main/AndroidManifest.xml @@ -1,4 +1,4 @@ + package="uk.co.chrisjenx.calligraphy3"> diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyActivityFactory.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyActivityFactory.java deleted file mode 100644 index e0214eb..0000000 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyActivityFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -package uk.co.chrisjenx.calligraphy; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; - -/** - * Created by chris on 09/11/14. - * For Calligraphy. - */ -interface CalligraphyActivityFactory { - - /** - * Used to Wrap the Activity onCreateView method. - * - * You implement this method like so in you base activity. - *
-     * {@code
-     * public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
-     *   return CalligraphyContextWrapper.get(getBaseContext()).onActivityCreateView(super.onCreateView(parent, name, context, attrs), attrs);
-     * }
-     * }
-     * 
- * - * @param parent parent view, can be null. - * @param view result of {@code super.onCreateView(parent, name, context, attrs)}, this might be null, which is fine. - * @param name Name of View we are trying to inflate - * @param context current context (normally the Activity's) - * @param attrs see {@link android.view.LayoutInflater.Factory2#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet)} @return the result from the activities {@code onCreateView()} - * @return The view passed in, or null if nothing was passed in. - * @see android.view.LayoutInflater.Factory2 - */ - View onActivityCreateView(View parent, View view, String name, Context context, AttributeSet attrs); -} diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java deleted file mode 100644 index 8650208..0000000 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java +++ /dev/null @@ -1,118 +0,0 @@ -package uk.co.chrisjenx.calligraphy; - -import android.app.Activity; -import android.content.Context; -import android.content.ContextWrapper; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; - -/** - * Created by chris on 19/12/2013 - * Project: Calligraphy - */ -public class CalligraphyContextWrapper extends ContextWrapper { - - private CalligraphyLayoutInflater mInflater; - - private final int mAttributeId; - - /** - * Uses the default configuration from {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} - * - * Remember if you are defining default in the - * {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} make sure this is initialised before - * the activity is created. - * - * @param base ContextBase to Wrap. - * @return ContextWrapper to pass back to the activity. - */ - public static ContextWrapper wrap(Context base) { - return new CalligraphyContextWrapper(base); - } - - /** - * You only need to call this IF you call - * {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig.Builder#disablePrivateFactoryInjection()} - * This will need to be called from the - * {@link android.app.Activity#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet)} - * method to enable view font injection if the view is created inside the activity onCreateView. - * - * You would implement this method like so in you base activity. - *
-     * {@code
-     * public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
-     *   return CalligraphyContextWrapper.onActivityCreateView(this, parent, super.onCreateView(parent, name, context, attrs), name, context, attrs);
-     * }
-     * }
-     * 
- * - * @param activity The activity the original that the ContextWrapper was attached too. - * @param parent Parent view from onCreateView - * @param view The View Created inside onCreateView or from super.onCreateView - * @param name The View name from onCreateView - * @param context The context from onCreateView - * @param attr The AttributeSet from onCreateView - * @return The same view passed in, or null if null passed in. - */ - public static View onActivityCreateView(Activity activity, View parent, View view, String name, Context context, AttributeSet attr) { - return get(activity).onActivityCreateView(parent, view, name, context, attr); - } - - /** - * Get the Calligraphy Activity Fragment Instance to allow callbacks for when views are created. - * - * @param activity The activity the original that the ContextWrapper was attached too. - * @return Interface allowing you to call onActivityViewCreated - */ - static CalligraphyActivityFactory get(Activity activity) { - if (!(activity.getLayoutInflater() instanceof CalligraphyLayoutInflater)) { - throw new RuntimeException("This activity does not wrap the Base Context! See CalligraphyContextWrapper.wrap(Context)"); - } - return (CalligraphyActivityFactory) activity.getLayoutInflater(); - } - - /** - * Uses the default configuration from {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} - * - * Remember if you are defining default in the - * {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} make sure this is initialised before - * the activity is created. - * - * @param base ContextBase to Wrap - */ - CalligraphyContextWrapper(Context base) { - super(base); - mAttributeId = CalligraphyConfig.get().getAttrId(); - } - - /** - * Override the default AttributeId, this will always take the custom attribute defined here - * and ignore the one set in {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig}. - * - * Remember if you are defining default in the - * {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} make sure this is initialised before - * the activity is created. - * - * @param base ContextBase to Wrap - * @param attributeId Attribute to lookup. - * @deprecated use {@link #wrap(android.content.Context)} - */ - @Deprecated - public CalligraphyContextWrapper(Context base, int attributeId) { - super(base); - mAttributeId = attributeId; - } - - @Override - public Object getSystemService(String name) { - if (LAYOUT_INFLATER_SERVICE.equals(name)) { - if (mInflater == null) { - mInflater = new CalligraphyLayoutInflater(LayoutInflater.from(getBaseContext()), this, mAttributeId, false); - } - return mInflater; - } - return super.getSystemService(name); - } - -} diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java deleted file mode 100644 index 6f9cfc1..0000000 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java +++ /dev/null @@ -1,311 +0,0 @@ -package uk.co.chrisjenx.calligraphy; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import org.xmlpull.v1.XmlPullParser; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -/** - * Created by chris on 19/12/2013 - * Project: Calligraphy - */ -class CalligraphyLayoutInflater extends LayoutInflater implements CalligraphyActivityFactory { - - private static final String[] sClassPrefixList = { - "android.widget.", - "android.webkit." - }; - - private final int mAttributeId; - private final CalligraphyFactory mCalligraphyFactory; - // Reflection Hax - private boolean mSetPrivateFactory = false; - private Field mConstructorArgs = null; - - protected CalligraphyLayoutInflater(Context context, int attributeId) { - super(context); - mAttributeId = attributeId; - mCalligraphyFactory = new CalligraphyFactory(attributeId); - setUpLayoutFactories(false); - } - - protected CalligraphyLayoutInflater(LayoutInflater original, Context newContext, int attributeId, final boolean cloned) { - super(original, newContext); - mAttributeId = attributeId; - mCalligraphyFactory = new CalligraphyFactory(attributeId); - setUpLayoutFactories(cloned); - } - - @Override - public LayoutInflater cloneInContext(Context newContext) { - return new CalligraphyLayoutInflater(this, newContext, mAttributeId, true); - } - - // === - // Wrapping goodies - // === - - - @Override - public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) { - setPrivateFactoryInternal(); - return super.inflate(parser, root, attachToRoot); - } - - /** - * We don't want to unnecessary create/set our factories if there are none there. We try to be - * as lazy as possible. - */ - private void setUpLayoutFactories(boolean cloned) { - if (cloned) return; - // If we are HC+ we get and set Factory2 otherwise we just wrap Factory1 - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - if (getFactory2() != null && !(getFactory2() instanceof WrapperFactory2)) { - // Sets both Factory/Factory2 - setFactory2(getFactory2()); - } - } - // We can do this as setFactory2 is used for both methods. - if (getFactory() != null && !(getFactory() instanceof WrapperFactory)) { - setFactory(getFactory()); - } - } - - @Override - public void setFactory(Factory factory) { - // Only set our factory and wrap calls to the Factory trying to be set! - if (!(factory instanceof WrapperFactory)) { - super.setFactory(new WrapperFactory(factory, this, mCalligraphyFactory)); - } else { - super.setFactory(factory); - } - } - - @Override - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public void setFactory2(Factory2 factory2) { - // Only set our factory and wrap calls to the Factory2 trying to be set! - if (!(factory2 instanceof WrapperFactory2)) { -// LayoutInflaterCompat.setFactory(this, new WrapperFactory2(factory2, mCalligraphyFactory)); - super.setFactory2(new WrapperFactory2(factory2, mCalligraphyFactory)); - } else { - super.setFactory2(factory2); - } - } - - private void setPrivateFactoryInternal() { - // Already tried to set the factory. - if (mSetPrivateFactory) return; - // Reflection (Or Old Device) skip. - if (!CalligraphyConfig.get().isReflection()) return; - // Skip if not attached to an activity. - if (!(getContext() instanceof Factory2)) { - mSetPrivateFactory = true; - return; - } - - final Method setPrivateFactoryMethod = ReflectionUtils - .getMethod(LayoutInflater.class, "setPrivateFactory"); - - if (setPrivateFactoryMethod != null) { - ReflectionUtils.invokeMethod(this, - setPrivateFactoryMethod, - new PrivateWrapperFactory2((Factory2) getContext(), this, mCalligraphyFactory)); - } - mSetPrivateFactory = true; - } - - // === - // LayoutInflater ViewCreators - // Works in order of inflation - // === - - /** - * The Activity onCreateView (PrivateFactory) is the third port of call for LayoutInflation. - * We opted to manual injection over aggressive reflection, this should be less fragile. - */ - @Override - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - public View onActivityCreateView(View parent, View view, String name, Context context, AttributeSet attrs) { - return mCalligraphyFactory.onViewCreated(createCustomViewInternal(parent, view, name, context, attrs), context, attrs); - } - - /** - * The LayoutInflater onCreateView is the fourth port of call for LayoutInflation. - * BUT only for none CustomViews. - */ - @Override - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - protected View onCreateView(View parent, String name, AttributeSet attrs) throws ClassNotFoundException { - return mCalligraphyFactory.onViewCreated(super.onCreateView(parent, name, attrs), - getContext(), attrs); - } - - /** - * The LayoutInflater onCreateView is the fourth port of call for LayoutInflation. - * BUT only for none CustomViews. - * Basically if this method doesn't inflate the View nothing probably will. - */ - @Override - protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException { - // This mimics the {@code PhoneLayoutInflater} in the way it tries to inflate the base - // classes, if this fails its pretty certain the app will fail at this point. - View view = null; - for (String prefix : sClassPrefixList) { - try { - view = createView(name, prefix, attrs); - } catch (ClassNotFoundException ignored) { - } - } - // In this case we want to let the base class take a crack - // at it. - if (view == null) view = super.onCreateView(name, attrs); - - return mCalligraphyFactory.onViewCreated(view, view.getContext(), attrs); - } - - /** - * 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. - * - * @param parent parent view - * @param view view if it has been inflated by this point, if this is not null this method - * just returns this value. - * @param name name of the thing to inflate. - * @param viewContext Context to inflate by if parent is null - * @param attrs Attr for this view which we can steal fontPath from too. - * @return view or the View we inflate in here. - */ - private View createCustomViewInternal(View parent, View view, String name, Context viewContext, AttributeSet 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().isCustomViewCreation()) return view; - if (view == null && name.indexOf('.') > -1) { - if (mConstructorArgs == null) - mConstructorArgs = ReflectionUtils.getField(LayoutInflater.class, "mConstructorArgs"); - - final Object[] mConstructorArgsArr = (Object[]) ReflectionUtils.getValue(mConstructorArgs, this); - final Object lastContext = mConstructorArgsArr[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. - mConstructorArgsArr[0] = viewContext; - ReflectionUtils.setValue(mConstructorArgs, this, mConstructorArgsArr); - try { - view = createView(name, null, attrs); - } catch (ClassNotFoundException ignored) { - } finally { - mConstructorArgsArr[0] = lastContext; - ReflectionUtils.setValue(mConstructorArgs, this, mConstructorArgsArr); - } - } - return view; - } - - // === - // Wrapper Factories for Pre/Post HC - // === - - /** - * Factory 1 is the first port of call for LayoutInflation - */ - private static class WrapperFactory implements Factory { - - private final Factory mFactory; - private final CalligraphyLayoutInflater mInflater; - private final CalligraphyFactory mCalligraphyFactory; - - public WrapperFactory(Factory factory, CalligraphyLayoutInflater inflater, CalligraphyFactory calligraphyFactory) { - mFactory = factory; - mInflater = inflater; - mCalligraphyFactory = calligraphyFactory; - } - - @Override - public View onCreateView(String name, Context context, AttributeSet attrs) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - return mCalligraphyFactory.onViewCreated( - mInflater.createCustomViewInternal( - null, mFactory.onCreateView(name, context, attrs), name, context, attrs - ), - context, attrs - ); - } - return mCalligraphyFactory.onViewCreated( - mFactory.onCreateView(name, context, attrs), - context, attrs - ); - } - } - - /** - * Factory 2 is the second port of call for LayoutInflation - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - private static class WrapperFactory2 implements Factory2 { - protected final Factory2 mFactory2; - protected final CalligraphyFactory mCalligraphyFactory; - - public WrapperFactory2(Factory2 factory2, CalligraphyFactory calligraphyFactory) { - mFactory2 = factory2; - mCalligraphyFactory = calligraphyFactory; - } - - @Override - public View onCreateView(String name, Context context, AttributeSet attrs) { - return mCalligraphyFactory.onViewCreated( - mFactory2.onCreateView(name, context, attrs), - context, attrs); - } - - @Override - public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { - return mCalligraphyFactory.onViewCreated( - mFactory2.onCreateView(parent, name, context, attrs), - context, attrs); - } - } - - /** - * Private factory is step three for Activity Inflation, this is what is attached to the - * Activity on HC+ devices. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB) - private static class PrivateWrapperFactory2 extends WrapperFactory2 { - - private final CalligraphyLayoutInflater mInflater; - - public PrivateWrapperFactory2(Factory2 factory2, CalligraphyLayoutInflater inflater, CalligraphyFactory calligraphyFactory) { - super(factory2, calligraphyFactory); - mInflater = inflater; - } - - @Override - public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { - return mCalligraphyFactory.onViewCreated( - mInflater.createCustomViewInternal(parent, - mFactory2.onCreateView(parent, name, context, attrs), - name, context, attrs - ), - context, attrs - ); - } - } - -} diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/ReflectionUtils.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/ReflectionUtils.java deleted file mode 100644 index 99c0d86..0000000 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/ReflectionUtils.java +++ /dev/null @@ -1,61 +0,0 @@ -package uk.co.chrisjenx.calligraphy; - -import android.util.Log; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -/** - * Created by chris on 17/12/14. - * For Calligraphy. - */ -class ReflectionUtils { - - private static final String TAG = ReflectionUtils.class.getSimpleName(); - - static Field getField(Class clazz, String fieldName) { - try { - final Field f = clazz.getDeclaredField(fieldName); - f.setAccessible(true); - return f; - } catch (NoSuchFieldException ignored) { - } - return null; - } - - static Object getValue(Field field, Object obj) { - try { - return field.get(obj); - } catch (IllegalAccessException ignored) { - } - return null; - } - - static void setValue(Field field, Object obj, Object value) { - try { - field.set(obj, value); - } catch (IllegalAccessException ignored) { - } - } - - static Method getMethod(Class clazz, String methodName) { - final Method[] methods = clazz.getMethods(); - for (Method method : methods) { - if (method.getName().equals(methodName)) { - method.setAccessible(true); - return method; - } - } - return null; - } - - static void invokeMethod(Object object, Method method, Object... args) { - try { - if (method == null) return; - method.invoke(object, args); - } catch (IllegalAccessException | InvocationTargetException e) { - Log.d(TAG, "Can't invoke method using reflection", e); - } - } -} diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyConfig.java similarity index 64% rename from calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java rename to calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyConfig.java index 2fb8f63..271c09e 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyConfig.java @@ -1,6 +1,5 @@ -package uk.co.chrisjenx.calligraphy; +package uk.co.chrisjenx.calligraphy3; -import android.os.Build; import android.text.TextUtils; import android.view.View; import android.widget.AutoCompleteTextView; @@ -61,28 +60,6 @@ private static void addAppCompatViews() { DEFAULT_STYLES.put(android.support.v7.widget.AppCompatCheckedTextView.class, android.R.attr.checkedTextViewStyle); } - private static CalligraphyConfig sInstance; - - /** - * Set the default Calligraphy Config - * - * @param calligraphyConfig the config build using the builder. - * @see uk.co.chrisjenx.calligraphy.CalligraphyConfig.Builder - */ - public static void initDefault(CalligraphyConfig calligraphyConfig) { - sInstance = calligraphyConfig; - } - - /** - * The current Calligraphy Config. - * If not set it will create a default config. - */ - public static CalligraphyConfig get() { - if (sInstance == null) - sInstance = new CalligraphyConfig(new Builder()); - return sInstance; - } - /** * Is a default font set? */ @@ -95,14 +72,6 @@ public static CalligraphyConfig get() { * Default Font Path Attr Id to lookup */ private final int mAttrId; - /** - * Use Reflection to inject the private factory. - */ - private final boolean mReflection; - /** - * Use Reflection to intercept CustomView inflation with the correct Context. - */ - private final boolean mCustomViewCreation; /** * Use Reflection to try to set typeface for custom views if they has setTypeface method */ @@ -113,21 +82,24 @@ public static CalligraphyConfig get() { private final Map, Integer> mClassStyleAttributeMap; /** * Collection of custom non-{@code TextView}'s registered for applying typeface during inflation - * @see uk.co.chrisjenx.calligraphy.CalligraphyConfig.Builder#addCustomViewWithSetTypeface(Class) + * @see CalligraphyConfig.Builder#addCustomViewWithSetTypeface(Class) */ private final Set> hasTypefaceViews; + /** + * An object that can map a resolved font name to another font name. + */ + private final FontMapper mFontMapper; - protected CalligraphyConfig(Builder builder) { + private CalligraphyConfig(Builder builder) { mIsFontSet = builder.isFontSet; mFontPath = builder.fontAssetPath; mAttrId = builder.attrId; - mReflection = builder.reflection; - mCustomViewCreation = builder.customViewCreation; mCustomViewTypefaceSupport = builder.customViewTypefaceSupport; final Map, Integer> tempMap = new HashMap<>(DEFAULT_STYLES); tempMap.putAll(builder.mStyleClassMap); mClassStyleAttributeMap = Collections.unmodifiableMap(tempMap); hasTypefaceViews = Collections.unmodifiableSet(builder.mHasTypefaceClasses); + mFontMapper = builder.fontMapper; } /** @@ -144,14 +116,6 @@ boolean isFontSet() { return mIsFontSet; } - public boolean isReflection() { - return mReflection; - } - - public boolean isCustomViewCreation() { - return mCustomViewCreation; - } - public boolean isCustomViewTypefaceSupport() { return mCustomViewTypefaceSupport; } @@ -171,19 +135,15 @@ public int getAttrId() { return mAttrId; } + public FontMapper getFontMapper() { + return mFontMapper; + } + public static class Builder { /** * Default AttrID if not set. */ public static final int INVALID_ATTR_ID = -1; - /** - * Use Reflection to inject the private factory. Doesn't exist pre HC. so defaults to false. - */ - private boolean reflection = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - /** - * Use Reflection to intercept CustomView inflation with the correct Context. - */ - private boolean customViewCreation = true; /** * Use Reflection during view creation to try change typeface via setTypeface method if it exists */ @@ -207,6 +167,8 @@ public static class Builder { private Set> mHasTypefaceClasses = new HashSet<>(); + private FontMapper fontMapper; + /** * This defaults to R.attr.fontPath. So only override if you want to use your own attrId. * @@ -231,56 +193,6 @@ public Builder setDefaultFontPath(String defaultFontAssetPath) { return this; } - /** - *

Turn of the use of Reflection to inject the private factory. - * This has operational consequences! Please read and understand before disabling. - * This is already disabled on pre Honeycomb devices. (API 11)

- * - *

If you disable this you will need to override your {@link android.app.Activity#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet)} - * as this is set as the {@link android.view.LayoutInflater} private factory.

- *
- * Use the following code in the Activity if you disable FactoryInjection: - *

-         * {@literal @}Override
-         * {@literal @}TargetApi(Build.VERSION_CODES.HONEYCOMB)
-         * public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
-         *   return CalligraphyContextWrapper.onActivityCreateView(this, parent, super.onCreateView(parent, name, context, attrs), name, context, attrs);
-         * }
-         * 
- */ - public Builder disablePrivateFactoryInjection() { - this.reflection = false; - return this; - } - - /** - * Due to the poor inflation order where custom views are created and never returned inside an - * {@code onCreateView(...)} method. We have to create CustomView's at the latest point in the - * overrideable injection flow. - * - * On HoneyComb+ this is inside the {@link android.app.Activity#onCreateView(android.view.View, String, android.content.Context, android.util.AttributeSet)} - * Pre HoneyComb this is in the {@link android.view.LayoutInflater.Factory#onCreateView(String, android.util.AttributeSet)} - * - * We wrap base implementations, so if you LayoutInflater/Factory/Activity creates the - * custom view before we get to this point, your view is used. (Such is the case with the - * TintEditText etc) - * - * The problem is, the native methods pass there parents context to the constructor in a really - * specific place. We have to mimic this in {@link uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater#createCustomViewInternal(android.view.View, android.view.View, String, android.content.Context, android.util.AttributeSet)} - * To mimic this we have to use reflection as the Class constructor args are hidden to us. - * - * We have discussed other means of doing this but this is the only semi-clean way of doing it. - * (Without having to do proxy classes etc). - * - * Calling this will of course speed up inflation by turning off reflection, but not by much, - * But if you want Calligraphy to inject the correct typeface then you will need to make sure your CustomView's - * are created before reaching the LayoutInflater onViewCreated. - */ - public Builder disableCustomViewInflation() { - this.customViewCreation = false; - return this; - } - /** * Add a custom style to get looked up. If you use a custom class that has a parent style * which is not part of the default android styles you will need to add it here. @@ -312,6 +224,11 @@ public Builder addCustomViewWithSetTypeface(Class clazz) { return this; } + public Builder setFontMapper(FontMapper fontMapper) { + this.fontMapper = fontMapper; + return this; + } + public CalligraphyConfig build() { this.isFontSet = !TextUtils.isEmpty(fontAssetPath); return new CalligraphyConfig(this); diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java similarity index 88% rename from calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java rename to calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java index abc43dc..ae1a218 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java @@ -1,4 +1,4 @@ -package uk.co.chrisjenx.calligraphy; +package uk.co.chrisjenx.calligraphy3; import android.annotation.SuppressLint; import android.annotation.TargetApi; @@ -15,6 +15,8 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Method; +import io.github.inflationx.viewpump.ReflectionUtils; + class CalligraphyFactory { private static final String ACTION_BAR_TITLE = "action_bar_title"; @@ -26,7 +28,7 @@ class CalligraphyFactory { * @param view view to check. * @return 2 element array, default to -1 unless a style has been found. */ - protected static int[] getStyleForTextView(TextView view) { + protected int[] getStyleForTextView(TextView view) { final int[] styleIds = new int[]{-1, -1}; // Try to find the specific actionbar styles if (isActionBarTitle(view)) { @@ -38,8 +40,8 @@ protected static int[] getStyleForTextView(TextView view) { } if (styleIds[0] == -1) { // Use TextAppearance as default style - styleIds[0] = CalligraphyConfig.get().getClassStyles().containsKey(view.getClass()) - ? CalligraphyConfig.get().getClassStyles().get(view.getClass()) + styleIds[0] = mCalligraphyConfig.getClassStyles().containsKey(view.getClass()) + ? mCalligraphyConfig.getClassStyles().get(view.getClass()) : android.R.attr.textAppearance; } return styleIds; @@ -94,10 +96,12 @@ protected static boolean matchesResourceIdName(View view, String matches) { return resourceEntryName.equalsIgnoreCase(matches); } + private final CalligraphyConfig mCalligraphyConfig; private final int[] mAttributeId; - public CalligraphyFactory(int attributeId) { - this.mAttributeId = new int[]{attributeId}; + public CalligraphyFactory(CalligraphyConfig calligraphyConfig) { + mCalligraphyConfig = calligraphyConfig; + this.mAttributeId = new int[]{calligraphyConfig.getAttrId()}; } /** @@ -140,10 +144,12 @@ void onViewCreatedInternal(View view, final Context context, AttributeSet attrs) textViewFont = CalligraphyUtils.pullFontPathFromTheme(context, styleForTextView[0], mAttributeId); } + textViewFont = applyFontMapper(textViewFont); + // Still need to defer the Native action bar, appcompat-v7:21+ uses the Toolbar underneath. But won't match these anyway. final boolean deferred = matchesResourceIdName(view, ACTION_BAR_TITLE) || matchesResourceIdName(view, ACTION_BAR_SUBTITLE); - CalligraphyUtils.applyFontToTextView(context, (TextView) view, CalligraphyConfig.get(), textViewFont, deferred); + CalligraphyUtils.applyFontToTextView(context, (TextView) view, mCalligraphyConfig, textViewFont, deferred); } // AppCompat API21+ The ActionBar doesn't inflate default Title/SubTitle, we need to scan the @@ -155,13 +161,16 @@ void onViewCreatedInternal(View view, final Context context, AttributeSet attrs) // Try to set typeface for custom views using interface method or via reflection if available if (view instanceof HasTypeface) { - Typeface typeface = getDefaultTypeface(context, resolveFontPath(context, attrs)); + String textViewFont = resolveFontPath(context, attrs); + textViewFont = applyFontMapper(textViewFont); + Typeface typeface = getDefaultTypeface(context, textViewFont); if (typeface != null) { ((HasTypeface) view).setTypeface(typeface); } - } else if (CalligraphyConfig.get().isCustomViewTypefaceSupport() && CalligraphyConfig.get().isCustomViewHasTypeface(view)) { + } else if (mCalligraphyConfig.isCustomViewTypefaceSupport() && mCalligraphyConfig.isCustomViewHasTypeface(view)) { final Method setTypeface = ReflectionUtils.getMethod(view.getClass(), "setTypeface"); String fontPath = resolveFontPath(context, attrs); + fontPath = applyFontMapper(fontPath); Typeface typeface = getDefaultTypeface(context, fontPath); if (setTypeface != null && typeface != null) { ReflectionUtils.invokeMethod(view, setTypeface, typeface); @@ -172,7 +181,7 @@ void onViewCreatedInternal(View view, final Context context, AttributeSet attrs) private Typeface getDefaultTypeface(Context context, String fontPath) { if (TextUtils.isEmpty(fontPath)) { - fontPath = CalligraphyConfig.get().getFontPath(); + fontPath = mCalligraphyConfig.getFontPath(); } if (!TextUtils.isEmpty(fontPath)) { return TypefaceUtils.load(context.getAssets(), fontPath); @@ -200,6 +209,11 @@ private String resolveFontPath(Context context, AttributeSet attrs) { return textViewFont; } + private String applyFontMapper(String textViewFont) { + FontMapper fontMapper = mCalligraphyConfig.getFontMapper(); + return fontMapper != null ? fontMapper.map(textViewFont) : textViewFont; + } + private static class ToolbarLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener { static String BLANK = " "; diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java new file mode 100644 index 0000000..b57dc26 --- /dev/null +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java @@ -0,0 +1,22 @@ +package uk.co.chrisjenx.calligraphy3; + +import android.view.View; + +import io.github.inflationx.viewpump.InflateResult; +import io.github.inflationx.viewpump.Interceptor; + +public class CalligraphyInterceptor implements Interceptor { + + private final CalligraphyFactory calligraphyFactory; + + public CalligraphyInterceptor(CalligraphyConfig calligraphyConfig) { + this.calligraphyFactory = new CalligraphyFactory(calligraphyConfig); + } + + @Override + public InflateResult intercept(Chain chain) { + InflateResult result = chain.proceed(chain.request()); + View viewWithTypeface = calligraphyFactory.onViewCreated(result.view(), result.context(), result.attrs()); + return result.toBuilder().view(viewWithTypeface).build(); + } +} diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyTypefaceSpan.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyTypefaceSpan.java similarity index 96% rename from calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyTypefaceSpan.java rename to calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyTypefaceSpan.java index debdd3e..8994a7c 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyTypefaceSpan.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyTypefaceSpan.java @@ -1,4 +1,4 @@ -package uk.co.chrisjenx.calligraphy; +package uk.co.chrisjenx.calligraphy3; import android.graphics.Paint; import android.graphics.Typeface; diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyUtils.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyUtils.java similarity index 99% rename from calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyUtils.java rename to calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyUtils.java index ab71cd9..be990b3 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyUtils.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyUtils.java @@ -1,4 +1,4 @@ -package uk.co.chrisjenx.calligraphy; +package uk.co.chrisjenx.calligraphy3; import android.content.Context; import android.content.res.AssetManager; @@ -97,7 +97,7 @@ public void afterTextChanged(Editable s) { /** * Useful for manually fonts to a TextView. Will not default back to font - * set in {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} + * set in {@link CalligraphyConfig} * * @param context Context * @param textView Not null, TextView to apply to. diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java new file mode 100644 index 0000000..ada8294 --- /dev/null +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java @@ -0,0 +1,5 @@ +package uk.co.chrisjenx.calligraphy3; + +public interface FontMapper { + String map(String font); +} diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/HasTypeface.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/HasTypeface.java similarity index 81% rename from calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/HasTypeface.java rename to calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/HasTypeface.java index 48950f9..e3ca0c6 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/HasTypeface.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/HasTypeface.java @@ -1,4 +1,4 @@ -package uk.co.chrisjenx.calligraphy; +package uk.co.chrisjenx.calligraphy3; import android.graphics.Typeface; @@ -8,7 +8,7 @@ *
  • Implementing this interface. You should only implements {@link #setTypeface(Typeface)} method.
  • *
  • Or via reflection. If custom view already has setTypeface method you can * register it during Calligraphy configuration - * {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig.Builder#addCustomViewWithSetTypeface(Class)}
  • + * {@link CalligraphyConfig.Builder#addCustomViewWithSetTypeface(Class)} * * First way is faster but encourage more effort from the developer to implements interface. Second one * requires less effort but works slowly cause reflection calls. diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/TypefaceUtils.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/TypefaceUtils.java similarity index 98% rename from calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/TypefaceUtils.java rename to calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/TypefaceUtils.java index 8ad3a8c..bad759f 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/TypefaceUtils.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/TypefaceUtils.java @@ -1,4 +1,4 @@ -package uk.co.chrisjenx.calligraphy; +package uk.co.chrisjenx.calligraphy3; import android.content.res.AssetManager; import android.graphics.Typeface; From 61554e505c97b2bfa58315fd8c8cab5646190026 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 31 Jan 2017 00:09:20 -0800 Subject: [PATCH 2/3] Remove FontMapper API --- .../sample/CalligraphyApplication.java | 7 ------- .../calligraphy3/CalligraphyConfig.java | 16 ---------------- .../calligraphy3/CalligraphyFactory.java | 9 --------- .../uk/co/chrisjenx/calligraphy3/FontMapper.java | 5 ----- 4 files changed, 37 deletions(-) delete mode 100644 calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java diff --git a/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java b/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java index 0a5405d..2622d94 100644 --- a/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java +++ b/CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java @@ -5,7 +5,6 @@ import io.github.inflationx.viewpump.ViewPump; import uk.co.chrisjenx.calligraphy3.CalligraphyConfig; import uk.co.chrisjenx.calligraphy3.CalligraphyInterceptor; -import uk.co.chrisjenx.calligraphy3.FontMapper; /** * Created by chris on 06/05/2014. @@ -21,12 +20,6 @@ public void onCreate() { new CalligraphyConfig.Builder() .setDefaultFontPath("fonts/Roboto-ThinItalic.ttf") .setFontAttrId(R.attr.fontPath) - .setFontMapper(new FontMapper() { - @Override - public String map(String font) { - return font; - } - }) .addCustomViewWithSetTypeface(CustomViewWithTypefaceSupport.class) .addCustomStyle(TextField.class, R.attr.textFieldStyle) .build())) diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyConfig.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyConfig.java index 271c09e..d5d9642 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyConfig.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyConfig.java @@ -85,10 +85,6 @@ private static void addAppCompatViews() { * @see CalligraphyConfig.Builder#addCustomViewWithSetTypeface(Class) */ private final Set> hasTypefaceViews; - /** - * An object that can map a resolved font name to another font name. - */ - private final FontMapper mFontMapper; private CalligraphyConfig(Builder builder) { mIsFontSet = builder.isFontSet; @@ -99,7 +95,6 @@ private CalligraphyConfig(Builder builder) { tempMap.putAll(builder.mStyleClassMap); mClassStyleAttributeMap = Collections.unmodifiableMap(tempMap); hasTypefaceViews = Collections.unmodifiableSet(builder.mHasTypefaceClasses); - mFontMapper = builder.fontMapper; } /** @@ -135,10 +130,6 @@ public int getAttrId() { return mAttrId; } - public FontMapper getFontMapper() { - return mFontMapper; - } - public static class Builder { /** * Default AttrID if not set. @@ -167,8 +158,6 @@ public static class Builder { private Set> mHasTypefaceClasses = new HashSet<>(); - private FontMapper fontMapper; - /** * This defaults to R.attr.fontPath. So only override if you want to use your own attrId. * @@ -224,11 +213,6 @@ public Builder addCustomViewWithSetTypeface(Class clazz) { return this; } - public Builder setFontMapper(FontMapper fontMapper) { - this.fontMapper = fontMapper; - return this; - } - public CalligraphyConfig build() { this.isFontSet = !TextUtils.isEmpty(fontAssetPath); return new CalligraphyConfig(this); diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java index ae1a218..b0009f7 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java @@ -144,8 +144,6 @@ void onViewCreatedInternal(View view, final Context context, AttributeSet attrs) textViewFont = CalligraphyUtils.pullFontPathFromTheme(context, styleForTextView[0], mAttributeId); } - textViewFont = applyFontMapper(textViewFont); - // Still need to defer the Native action bar, appcompat-v7:21+ uses the Toolbar underneath. But won't match these anyway. final boolean deferred = matchesResourceIdName(view, ACTION_BAR_TITLE) || matchesResourceIdName(view, ACTION_BAR_SUBTITLE); @@ -162,7 +160,6 @@ void onViewCreatedInternal(View view, final Context context, AttributeSet attrs) // Try to set typeface for custom views using interface method or via reflection if available if (view instanceof HasTypeface) { String textViewFont = resolveFontPath(context, attrs); - textViewFont = applyFontMapper(textViewFont); Typeface typeface = getDefaultTypeface(context, textViewFont); if (typeface != null) { ((HasTypeface) view).setTypeface(typeface); @@ -170,7 +167,6 @@ void onViewCreatedInternal(View view, final Context context, AttributeSet attrs) } else if (mCalligraphyConfig.isCustomViewTypefaceSupport() && mCalligraphyConfig.isCustomViewHasTypeface(view)) { final Method setTypeface = ReflectionUtils.getMethod(view.getClass(), "setTypeface"); String fontPath = resolveFontPath(context, attrs); - fontPath = applyFontMapper(fontPath); Typeface typeface = getDefaultTypeface(context, fontPath); if (setTypeface != null && typeface != null) { ReflectionUtils.invokeMethod(view, setTypeface, typeface); @@ -209,11 +205,6 @@ private String resolveFontPath(Context context, AttributeSet attrs) { return textViewFont; } - private String applyFontMapper(String textViewFont) { - FontMapper fontMapper = mCalligraphyConfig.getFontMapper(); - return fontMapper != null ? fontMapper.map(textViewFont) : textViewFont; - } - private static class ToolbarLayoutListener implements ViewTreeObserver.OnGlobalLayoutListener { static String BLANK = " "; diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java deleted file mode 100644 index ada8294..0000000 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/FontMapper.java +++ /dev/null @@ -1,5 +0,0 @@ -package uk.co.chrisjenx.calligraphy3; - -public interface FontMapper { - String map(String font); -} From 4801a112bff8d8c4d09dac5a9e5c50ce871f81e3 Mon Sep 17 00:00:00 2001 From: James Barr Date: Tue, 31 Jan 2017 00:10:52 -0800 Subject: [PATCH 3/3] MinSdk 14 and rename class --- CalligraphySample/build.gradle | 2 +- calligraphy/build.gradle | 4 ++-- .../{CalligraphyFactory.java => Calligraphy.java} | 12 ++++++------ .../calligraphy3/CalligraphyInterceptor.java | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) rename calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/{CalligraphyFactory.java => Calligraphy.java} (96%) diff --git a/CalligraphySample/build.gradle b/CalligraphySample/build.gradle index 19f0133..71327f4 100644 --- a/CalligraphySample/build.gradle +++ b/CalligraphySample/build.gradle @@ -5,7 +5,7 @@ android { buildToolsVersion "24.0.0" defaultConfig { - minSdkVersion 8 + minSdkVersion 14 targetSdkVersion 24 versionCode project.ext.versionCodeInt versionName version diff --git a/calligraphy/build.gradle b/calligraphy/build.gradle index ec5b5cf..7e2de70 100644 --- a/calligraphy/build.gradle +++ b/calligraphy/build.gradle @@ -5,7 +5,7 @@ android { buildToolsVersion "24.0.0" defaultConfig { - minSdkVersion 7 + minSdkVersion 14 targetSdkVersion 24 versionCode project.ext.versionCodeInt versionName version @@ -21,7 +21,7 @@ android { } dependencies { - compile 'io.github.inflationx:viewpump:0.1.0-SNAPSHOT' + compile 'io.github.inflationx:viewpump:0.1.1-SNAPSHOT' compile 'com.android.support:appcompat-v7:24.0.0' } diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/Calligraphy.java similarity index 96% rename from calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java rename to calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/Calligraphy.java index b0009f7..6b43fbf 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyFactory.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/Calligraphy.java @@ -17,7 +17,7 @@ import io.github.inflationx.viewpump.ReflectionUtils; -class CalligraphyFactory { +class Calligraphy { private static final String ACTION_BAR_TITLE = "action_bar_title"; private static final String ACTION_BAR_SUBTITLE = "action_bar_subtitle"; @@ -99,7 +99,7 @@ protected static boolean matchesResourceIdName(View view, String matches) { private final CalligraphyConfig mCalligraphyConfig; private final int[] mAttributeId; - public CalligraphyFactory(CalligraphyConfig calligraphyConfig) { + public Calligraphy(CalligraphyConfig calligraphyConfig) { mCalligraphyConfig = calligraphyConfig; this.mAttributeId = new int[]{calligraphyConfig.getAttrId()}; } @@ -209,14 +209,14 @@ private static class ToolbarLayoutListener implements ViewTreeObserver.OnGlobalL static String BLANK = " "; - private final WeakReference mCalligraphyFactory; + private final WeakReference mCalligraphyFactory; private final WeakReference mContextRef; private final WeakReference mToolbarReference; private final CharSequence originalSubTitle; - private ToolbarLayoutListener(final CalligraphyFactory calligraphyFactory, + private ToolbarLayoutListener(final Calligraphy calligraphy, final Context context, Toolbar toolbar) { - mCalligraphyFactory = new WeakReference<>(calligraphyFactory); + mCalligraphyFactory = new WeakReference<>(calligraphy); mContextRef = new WeakReference<>(context); mToolbarReference = new WeakReference<>(toolbar); originalSubTitle = toolbar.getSubtitle(); @@ -227,7 +227,7 @@ private ToolbarLayoutListener(final CalligraphyFactory calligraphyFactory, @Override public void onGlobalLayout() { final Toolbar toolbar = mToolbarReference.get(); final Context context = mContextRef.get(); - final CalligraphyFactory factory = mCalligraphyFactory.get(); + final Calligraphy factory = mCalligraphyFactory.get(); if (toolbar == null) return; if (factory == null || context == null) { removeSelf(toolbar); diff --git a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java index b57dc26..f683740 100644 --- a/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java +++ b/calligraphy/src/main/java/uk/co/chrisjenx/calligraphy3/CalligraphyInterceptor.java @@ -7,16 +7,16 @@ public class CalligraphyInterceptor implements Interceptor { - private final CalligraphyFactory calligraphyFactory; + private final Calligraphy calligraphy; public CalligraphyInterceptor(CalligraphyConfig calligraphyConfig) { - this.calligraphyFactory = new CalligraphyFactory(calligraphyConfig); + this.calligraphy = new Calligraphy(calligraphyConfig); } @Override public InflateResult intercept(Chain chain) { InflateResult result = chain.proceed(chain.request()); - View viewWithTypeface = calligraphyFactory.onViewCreated(result.view(), result.context(), result.attrs()); + View viewWithTypeface = calligraphy.onViewCreated(result.view(), result.context(), result.attrs()); return result.toBuilder().view(viewWithTypeface).build(); } }