I am creating a Richtext(WXTextView.java) view component in Weex by extending WXComponent. As Richtext component is not available in weex android sdk and "v-html" tag is also not supported in weex text component.
When my Richtext element is wrapped inside a div, the element is not visible. I have to manually add height to its parent div to make it visible.
<div class="parent">
<textView
ref="nativeTextView"
:style="{
color: '#ff6600',
fontSize: '40px',
maxLine: 2,
borderWidth: 2,
borderStyle: 'solid',
borderColor: 'green',
}"
text="ABCDEF"
/>
</div>
Giving height to the parent doesn't solve my purpose because text length is dynamic. I want to make this behavior just like default weex text component supporting rich text.
WXTextView.java
public class WXTextView extends WXComponent<TextView> {
private WXVContainer mContainer;
private int mHeight;
public WXTextView(WXSDKInstance instance, WXDomObject dom, WXVContainer parent) {
super(instance, dom, parent);
mContainer = parent;
}
@Override
protected TextView initComponentHostView(@NonNull Context context) {
TextView textView = new TextView(context);
setProperty(WXComponent.PROP_FIXED_SIZE, WXComponent.PROP_FS_WRAP_CONTENT);
textView.setIncludeFontPadding(false);
textView.setTextSize(WXText.sDEFAULT_SIZE);
return textView;
}
@WXComponentProp(name = "text")
public void setText(String text) {
getHostView().setText(Html.fromHtml(text));
updateUI();
}
private void updateUI() {
ViewGroup.LayoutParams params = mContainer.getRealView().getLayoutParams();
params.height = getHeight();
mContainer.getRealView().setLayoutParams(params);
mContainer.getRealView().invalidate();
}
@WXComponentProp(name = "ellipsize")
public void setEllipsize(String positionString) {
try {
int position = Integer.parseInt(positionString);
TextUtils.TruncateAt truncateType;
switch (position) {
case 0:
truncateType = TextUtils.TruncateAt.START;
break;
case 1:
truncateType = TextUtils.TruncateAt.MIDDLE;
break;
default:
truncateType = TextUtils.TruncateAt.END;
break;
}
getHostView().setEllipsize(truncateType);
updateUI();
} catch (Exception exception) {
exception.printStackTrace();
}
}
@WXComponentProp(name = "maxLine")
public void setMaxLine(String lineString) {
try {
int lineCount = Integer.parseInt(lineString);
getHostView().setMaxLines(lineCount);
updateUI();
} catch (Exception exception) {
exception.printStackTrace();
}
}
@JSMethod
public void getElementSpecs(JSCallback callback){
Log.d("nikhil", "android getHeight: " + getHostView().getHeight());
Map<String, Object> data = new HashMap<>();
data.put("width", getHostView().getMeasuredWidth());
data.put("height", getHostView().getMeasuredHeight());
data.put("positionX", getHostView().getX());
data.put("positionY", getHostView().getY());
callback.invoke(data);
}
@WXComponentProp(name = "color")
public void setColor(String color) {
getHostView().setTextColor(Color.parseColor(color));
}
@WXComponentProp(name = "fontSize")
public void setFontSize(String sizeString) {
int lastIndex = sizeString.indexOf("px");
if (lastIndex == -1) {
lastIndex = sizeString.length();
}
sizeString = sizeString.substring(0, lastIndex);
int size = Integer.parseInt(sizeString);
getHostView().setTextSize(size);
updateUI();
}
public int getHeight() {
getHostView().setText(getHostView().getText());
getHostView().setTextSize(TypedValue.COMPLEX_UNIT_PX, getHostView().getTextSize());
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(mContainer.getRealView().getLayoutParams().width,
View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
getHostView().measure(widthMeasureSpec, heightMeasureSpec);
mHeight = getHostView().getMeasuredHeight();
return mHeight;
}
}
Text is the most complicated component in Weex. In order to achieve similar behavior like weex text, you need extend WXDomObject as text extend WXTextDomObject, and implement your own text measure function.
In fact, I have written a richtext component in weex which will be released soon.