Android: impl font & hint font for input
This commit is contained in:
parent
489fea0839
commit
ae62a76160
@ -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);
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user