HarmonyOS实战:自定义view

一、自定义组件

鸿蒙自定义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);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值