From ae62a761603a5ce22db67ba51aa3dfe2307f3ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8A=B2=E9=B9=8F?= Date: Tue, 20 Jul 2021 15:48:09 +0800 Subject: [PATCH] Android: impl font & hint font for input --- .../main/java/pub/doric/shader/InputNode.java | 119 +++++++++++++++++- .../pub/doric/shader/input/CustomHint.java | 35 ++++++ .../input/CustomMetricAffectingSpan.java | 45 +++++++ 3 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 doric-android/doric/src/main/java/pub/doric/shader/input/CustomHint.java create mode 100644 doric-android/doric/src/main/java/pub/doric/shader/input/CustomMetricAffectingSpan.java diff --git a/doric-android/doric/src/main/java/pub/doric/shader/InputNode.java b/doric-android/doric/src/main/java/pub/doric/shader/InputNode.java index 1376f76d..834325c2 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/InputNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/InputNode.java @@ -16,6 +16,7 @@ package pub.doric.shader; import android.content.Context; +import android.graphics.Typeface; import android.text.Editable; import android.text.InputFilter; import android.text.InputType; @@ -31,6 +32,8 @@ import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.TextView; +import androidx.core.content.res.ResourcesCompat; + import com.github.pengfeizhou.jscore.ArchiveException; import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSONBuilder; @@ -46,6 +49,10 @@ import pub.doric.async.AsyncResult; import pub.doric.extension.bridge.DoricMethod; import pub.doric.extension.bridge.DoricPlugin; import pub.doric.extension.bridge.DoricPromise; +import pub.doric.shader.input.CustomHint; +import pub.doric.utils.DoricLog; + +import static pub.doric.utils.DoricUtils.dp2px; /** * @Description: pub.doric.shader @@ -59,6 +66,10 @@ public class InputNode extends ViewNode implements TextWatcher, View.O private String onFocusChangeId; private String beforeTextChangeId; + private String hintText; + private String hintFont; + private float textSize; + public InputNode(DoricContext doricContext) { super(doricContext); mInputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); @@ -72,9 +83,67 @@ public class InputNode extends ViewNode implements TextWatcher, View.O editText.setBackground(null); editText.setGravity(Gravity.START | Gravity.TOP); editText.setFilters(new InputFilter[]{this}); + + textSize = editText.getTextSize(); return editText; } + @Override + public void blend(JSObject jsObject) { + super.blend(jsObject); + + CustomHint customHint; + if (hintFont != null) { + if (hintText != null) { + String font = hintFont; + String fontPath = ""; + String fontName = font; + if (font.contains("/")) { + int separatorIndex = font.lastIndexOf("/"); + fontPath = font.substring(0, separatorIndex + 1); + fontName = font.substring(separatorIndex + 1); + } + + if (fontName.endsWith(".ttf")) { + fontName = fontName.replace(".ttf", ""); + } + + int resId = getContext().getResources().getIdentifier( + fontName.toLowerCase(), + "font", + getContext().getPackageName()); + if (resId > 0) { + try { + Typeface iconFont = ResourcesCompat.getFont(getContext(), resId); + customHint = new CustomHint(iconFont, hintText, textSize); + + mView.setHint(customHint); + } catch (Exception e) { + DoricLog.e("Error Font asset " + font + " in res/font"); + } + + } else { + fontName = fontPath + + fontName + + ".ttf"; + try { + Typeface iconFont = Typeface.createFromAsset(getContext().getAssets(), fontName); + customHint = new CustomHint(iconFont, hintText, textSize); + + mView.setHint(customHint); + } catch (Exception e) { + e.printStackTrace(); + DoricLog.e(font + " not found in Assets"); + } + } + } + } else { + if (hintText != null) { + mView.setHint(hintText); + } + } + } + @Override protected void blend(EditText view, String name, JSValue prop) { switch (name) { @@ -100,6 +169,7 @@ public class InputNode extends ViewNode implements TextWatcher, View.O view.setSelection(text.length()); break; case "textSize": + textSize = dp2px(prop.asNumber().toFloat()); view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, prop.asNumber().toFloat()); break; case "textColor": @@ -107,13 +177,60 @@ public class InputNode extends ViewNode implements TextWatcher, View.O break; case "textAlignment": view.setGravity(prop.asNumber().toInt()); + break; + case "font": + if (!prop.isString()) { + return; + } + String font = prop.asString().toString(); + String fontPath = ""; + String fontName = font; + if (font.contains("/")) { + int separatorIndex = font.lastIndexOf("/"); + fontPath = font.substring(0, separatorIndex + 1); + fontName = font.substring(separatorIndex + 1); + } + + if (fontName.endsWith(".ttf")) { + fontName = fontName.replace(".ttf", ""); + } + + int resId = getContext().getResources().getIdentifier( + fontName.toLowerCase(), + "font", + getContext().getPackageName()); + if (resId > 0) { + try { + Typeface iconFont = ResourcesCompat.getFont(getContext(), resId); + view.setTypeface(iconFont); + } catch (Exception e) { + DoricLog.e("Error Font asset " + font + " in res/font"); + } + + } else { + fontName = fontPath + + fontName + + ".ttf"; + try { + Typeface iconFont = Typeface.createFromAsset(getContext().getAssets(), fontName); + view.setTypeface(iconFont); + } catch (Exception e) { + e.printStackTrace(); + DoricLog.e(font + " not found in Assets"); + } + + } + break; case "hintText": - view.setHint(prop.asString().toString()); + this.hintText = prop.asString().toString(); break; case "hintTextColor": view.setHintTextColor(prop.asNumber().toInt()); break; + case "hintFont": + this.hintFont = prop.asString().toString(); + break; case "multiline": if (prop.asBoolean().value()) { view.setInputType(view.getInputType() | InputType.TYPE_TEXT_FLAG_MULTI_LINE); diff --git a/doric-android/doric/src/main/java/pub/doric/shader/input/CustomHint.java b/doric-android/doric/src/main/java/pub/doric/shader/input/CustomHint.java new file mode 100644 index 00000000..67dd602d --- /dev/null +++ b/doric-android/doric/src/main/java/pub/doric/shader/input/CustomHint.java @@ -0,0 +1,35 @@ +package pub.doric.shader.input; + +import android.graphics.Typeface; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.style.MetricAffectingSpan; + +public class CustomHint extends SpannableString { + public CustomHint(final CharSequence source, final int style) { + this(null, source, style, null); + } + + public CustomHint(final CharSequence source, final Float size) { + this(null, source, size); + } + + public CustomHint(final CharSequence source, final int style, final Float size) { + this(null, source, style, size); + } + + public CustomHint(final Typeface typeface, final CharSequence source, final int style) { + this(typeface, source, style, null); + } + + public CustomHint(final Typeface typeface, final CharSequence source, final Float size) { + this(typeface, source, null, size); + } + + public CustomHint(final Typeface typeface, final CharSequence source, final Integer style, final Float size) { + super(source); + + MetricAffectingSpan typefaceSpan = new CustomMetricAffectingSpan(typeface, style, size); + setSpan(typefaceSpan, 0, source.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + } +} \ No newline at end of file diff --git a/doric-android/doric/src/main/java/pub/doric/shader/input/CustomMetricAffectingSpan.java b/doric-android/doric/src/main/java/pub/doric/shader/input/CustomMetricAffectingSpan.java new file mode 100644 index 00000000..3ad8a895 --- /dev/null +++ b/doric-android/doric/src/main/java/pub/doric/shader/input/CustomMetricAffectingSpan.java @@ -0,0 +1,45 @@ +package pub.doric.shader.input; + +import android.graphics.Typeface; +import android.text.TextPaint; +import android.text.style.MetricAffectingSpan; + +public class CustomMetricAffectingSpan extends MetricAffectingSpan { + private final Typeface _typeface; + private final Float _newSize; + private final Integer _newStyle; + + public CustomMetricAffectingSpan(Float size) { + this(null, null, size); + } + + public CustomMetricAffectingSpan(Float size, Integer style) { + this(null, style, size); + } + + public CustomMetricAffectingSpan(Typeface type, Integer style, Float size) { + this._typeface = type; + this._newStyle = style; + this._newSize = size; + } + + @Override + public void updateDrawState(TextPaint ds) { + applyNewSize(ds); + } + + @Override + public void updateMeasureState(TextPaint paint) { + applyNewSize(paint); + } + + private void applyNewSize(TextPaint paint) { + if (this._newStyle != null) + paint.setTypeface(Typeface.create(this._typeface, this._newStyle)); + else + paint.setTypeface(this._typeface); + + if (this._newSize != null) + paint.setTextSize(this._newSize); + } +} \ No newline at end of file