一、自定义组件
鸿蒙自定义view的实现方式是继承Component、实现DrawTask接口。然后在构造函数里面调用addDrawTask(this)。代码如下:
public class View extends Component implements Component.DrawTask {
protected Context mContext;
/**
* This view is visible.
* Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
* android:visibility}.
*/
public static final int VISIBLE = Component.VISIBLE;
/**
* This view is invisible, but it still takes up space for layout purposes.
* Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
* android:visibility}.
*/
public static final int INVISIBLE = Component.INVISIBLE;
/**
* This view is invisible, and it doesn't take any space for layout
* purposes. Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
* android:visibility}.
*/
public static final int GONE = Component.HIDE;
public View(Context context) {
super(context);
initContext(context);
}
public View(Context context, AttrSet attrSet) {
super(context, attrSet);
initContext(context);
}
public View(Context context, AttrSet attrSet, String styleName) {
super(context, attrSet, styleName);
initContext(context);
}
public View(Context context, AttrSet attrSet, int resId) {
super(context, attrSet, resId);
initContext(context);
}
private void initContext(Context context){
mContext = context;
init();
}
protected void init(){
addDrawTask(this::onDraw);
}
protected int mWidth;
protected int mHeight;
@Override
public void onDraw(Component component, Canvas canvas) {
mComponent = component;
mWidth = component.getWidth();
mHeight = component.getHeight();
}
」
跟着源码发现,Component对象里面有两个DrawTask对象,addDrawTask也可以添加两种类型的DrawTask。
因此可以在自定义view的类里面定义两个DrawTask对象,然后通过addDrawTask分别添加
private DrawTask drawTask1 = new DrawTask(){
@Override
public void onDraw(Component component, Canvas canvas) {
//绘制
}
};
protectd void init(){
addDrawTask(drawTask1, DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
addDrawTask(drawTask2, DrawTask.BETWEEN_CONTENT_AND_FOREGROUND);
}
也可以为现有控件添加DrawTask,如Text控件,设置其他效果。
二、绘制相关api
Android有关绘制常见的类有Canvas、Paint、Rect、Color、RectF等。对应鸿蒙的是Canvas、Paint、Rect、Color、RectFloat。虽然大致上差不多,但是在一些方法的调用上有些不同的,对这些不同的地方,我做了一些封装,如下:
public class Paint extends ohos.agp.render.Paint {
public static final int ANTI_ALIAS_FLAG = 0x01;
public void setColor(int newColor) {
super.setColor(new Color(newColor));
}
public void setTextAlign(Align align) {
super.setTextAlign(align.nativeInt);
}
public Rect getTextBounds(String text, int start, int end, Rect bounds) {
bounds = new Rect(super.getTextBounds(text));
return bounds;
}
public void setStyle(Paint.Style style) {
super.setStyle(style.nativeInt);
}
public void setFlags(int flag){
//未找到HarmonyOS系统上对应的api,暂时什么都不做
}
public void setTextSize(float mDateTextSize) {
setTextSize((int)mDateTextSize);
}
public enum Align {
/**
* The text is drawn to the right of the x,y origin
*/
LEFT (TextAlignment.LEFT),
/**
* The text is drawn centered horizontally on the x,y origin
*/
CENTER (TextAlignment.CENTER),
/**
* The text is drawn to the left of the x,y origin
*/
RIGHT (TextAlignment.RIGHT);
private Align(int nativeInt) {
this.nativeInt = nativeInt;
}
final int nativeInt;
}
public enum Style {
/**
* Geometry and text drawn with this style will be filled, ignoring all
* stroke-related settings in the paint.
*/
FILL (ohos.agp.render.Paint.Style.FILL_STYLE),
/**
* Geometry and text drawn with this style will be stroked, respecting
* the stroke-related fields on the paint.
*/
STROKE (ohos.agp.render.Paint.Style.STROKE_STYLE),
/**
* Geometry and text drawn with this style will be both filled and
* stroked at the same time, respecting the stroke-related fields on
* the paint. This mode can give unexpected results if the geometry
* is oriented counter-clockwise. This restriction does not apply to
* either FILL or STROKE.
*/
FILL_AND_STROKE (ohos.agp.render.Paint.Style.FILLANDSTROKE_STYLE);
Style(ohos.agp.render.Paint.Style nativeInt) {
this.nativeInt = nativeInt;
}
final ohos.agp.render.Paint.Style nativeInt;
}
}
public class Color extends ohos.agp.utils.Color {
public static final int BLACK = ohos.agp.utils.Color.BLACK.getValue();
public static final int BLUE = ohos.agp.utils.Color.BLUE.getValue();
public static final int CYAN = ohos.agp.utils.Color.CYAN.getValue();
public static final int DKGRAY = ohos.agp.utils.Color.DKGRAY.getValue();
public static final int GRAY = ohos.agp.utils.Color.GRAY.getValue();
public static final int GREEN = ohos.agp.utils.Color.GREEN.getValue();
public static final int LTGRAY = ohos.agp.utils.Color.LTGRAY.getValue();
public static final int MAGENTA = ohos.agp.utils.Color.MAGENTA.getValue();
public static final int RED = ohos.agp.utils.Color.RED.getValue();
public static final int TRANSPARENT = ohos.agp.utils.Color.TRANSPARENT.getValue();
public static final int WHITE = ohos.agp.utils.Color.WHITE.getValue();
public static final int YELLOW = ohos.agp.utils.Color.YELLOW.getValue();
public Color(int color) {
super(color);
}
}
/**
* 代理 系统的canvas
*/
public class Canvas {
private ohos.agp.render.Canvas mCanvas;
public Canvas(ohos.agp.render.Canvas mCanvas) {
this.mCanvas = mCanvas;
}
public ohos.agp.render.Canvas getmCanvas() {
return mCanvas;
}
public int save() {
return mCanvas.save();
}
public void clipRect(float i, int i1, float mWidth, float changeHeight) {
mCanvas.clipRect(i, i1, mWidth, changeHeight);
}
public void drawColor(int i, BlendMode color) {
mCanvas.drawColor(i, color);
}
public void restore() {
mCanvas.restore();
}
public void drawPath(Path mPath, com.utility.widget.Paint mFramePaint) {
mCanvas.drawPath(mPath, mFramePaint);
}
public void drawLine(float v, float i, float v1, float v2, com.utility.widget.Paint mPaint) {
mCanvas.drawLine(v, i, v1, v2, mPaint);
}
public void drawPoint(float x, float y, com.utility.widget.Paint mPaint) {
mCanvas.drawPoint(x, y, mPaint);
}
public void drawCircle(float locX, float v, float radius, com.utility.widget.Paint linePaint) {
mCanvas.drawCircle(locX, v, radius, linePaint);
}
public void restoreToCount(int restoreCount) {
mCanvas.restoreToCount(restoreCount);
}
public void translate(int i, int i1) {
mCanvas.translate(i, i1);
}
public void rotate(int i) {
mCanvas.rotate(i);
}
public void drawRect(float left, float v, float right, float bottom, com.utility.widget.Paint rectPaint) {
mCanvas.drawRect(left, v, right, bottom, rectPaint);
}
public void drawText(String text, float x, float y, Paint paint) {
if (mCanvas == null) return;
mCanvas.drawText(paint, text, x, y);
}
public void drawText(Paint paint, String text, float x, float y) {
if (mCanvas == null) return;
mCanvas.drawText(paint, text, x, y);
}
public void drawRoundRect(RectFloat oval4, float textWidth, float textWidth1, com.utility.widget.Paint rectPaint) {
mCanvas.drawRoundRect(oval4, textWidth, textWidth1, rectPaint);
}
public void drawArc(RectFloat rectF, Arc arc, com.utility.widget.Paint paint) {
mCanvas.drawArc(rectF, arc, paint);
}
}