Android: impl font & hint font for input

This commit is contained in:
王劲鹏 2021-07-20 15:48:09 +08:00 committed by osborn
parent 489fea0839
commit ae62a76160
3 changed files with 198 additions and 1 deletions

View File

@ -16,6 +16,7 @@
package pub.doric.shader; package pub.doric.shader;
import android.content.Context; import android.content.Context;
import android.graphics.Typeface;
import android.text.Editable; import android.text.Editable;
import android.text.InputFilter; import android.text.InputFilter;
import android.text.InputType; import android.text.InputType;
@ -31,6 +32,8 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.content.res.ResourcesCompat;
import com.github.pengfeizhou.jscore.ArchiveException; import com.github.pengfeizhou.jscore.ArchiveException;
import com.github.pengfeizhou.jscore.JSDecoder; import com.github.pengfeizhou.jscore.JSDecoder;
import com.github.pengfeizhou.jscore.JSONBuilder; 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.DoricMethod;
import pub.doric.extension.bridge.DoricPlugin; import pub.doric.extension.bridge.DoricPlugin;
import pub.doric.extension.bridge.DoricPromise; 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 * @Description: pub.doric.shader
@ -59,6 +66,10 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
private String onFocusChangeId; private String onFocusChangeId;
private String beforeTextChangeId; private String beforeTextChangeId;
private String hintText;
private String hintFont;
private float textSize;
public InputNode(DoricContext doricContext) { public InputNode(DoricContext doricContext) {
super(doricContext); super(doricContext);
mInputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); mInputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@ -72,9 +83,67 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
editText.setBackground(null); editText.setBackground(null);
editText.setGravity(Gravity.START | Gravity.TOP); editText.setGravity(Gravity.START | Gravity.TOP);
editText.setFilters(new InputFilter[]{this}); editText.setFilters(new InputFilter[]{this});
textSize = editText.getTextSize();
return editText; 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 @Override
protected void blend(EditText view, String name, JSValue prop) { protected void blend(EditText view, String name, JSValue prop) {
switch (name) { switch (name) {
@ -100,6 +169,7 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
view.setSelection(text.length()); view.setSelection(text.length());
break; break;
case "textSize": case "textSize":
textSize = dp2px(prop.asNumber().toFloat());
view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, prop.asNumber().toFloat()); view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, prop.asNumber().toFloat());
break; break;
case "textColor": case "textColor":
@ -107,13 +177,60 @@ public class InputNode extends ViewNode<EditText> implements TextWatcher, View.O
break; break;
case "textAlignment": case "textAlignment":
view.setGravity(prop.asNumber().toInt()); 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; break;
case "hintText": case "hintText":
view.setHint(prop.asString().toString()); this.hintText = prop.asString().toString();
break; break;
case "hintTextColor": case "hintTextColor":
view.setHintTextColor(prop.asNumber().toInt()); view.setHintTextColor(prop.asNumber().toInt());
break; break;
case "hintFont":
this.hintFont = prop.asString().toString();
break;
case "multiline": case "multiline":
if (prop.asBoolean().value()) { if (prop.asBoolean().value()) {
view.setInputType(view.getInputType() | InputType.TYPE_TEXT_FLAG_MULTI_LINE); view.setInputType(view.getInputType() | InputType.TYPE_TEXT_FLAG_MULTI_LINE);

View File

@ -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);
}
}

View File

@ -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);
}
}