Android 自定义View :虚线矩形

预览效果:

 涉及参数:

斜线起点坐标(斜线可以忽略)
斜线终点坐标(斜线可以忽略)
矩形左上角坐标
矩形右下角坐标

其中,前两个参数用于绘制预览效果中矩形上方的斜线,如果不需要可以移除。

本案例涉及视频外一个点指向视频内某块区域,因此参数略微复杂,除斜线起点坐标为实际坐标外,其他三个参数为百分比,例如矩形左上角坐标(0.1,0.1)表示位于相对于视频左上角0.1*weight,0.1*height处。

自定义View代码:

package com.example.movie;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;

public class DashLineView extends View {

    private static final String TAG = "DashLineView";
    private Paint mPaint;
    private Path mPath;
    private int startX;
    private int startY;
    private float endX;
    private float endY;
    private float LUX;
    private float LUY;
    private float RDX;
    private float RDY;
    private int VIDEO_WIDTH = 1200;
    private int VIDEO_MARGIN_LEFT = 350;
    private int VIDEO_MARGIN_TOP = 200;



    public DashLineView(Context context, AttributeSet attrs) {

        super(context, attrs);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mPaint.setColor(Color.GRAY);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(3);
        //线段15px,间隔5px,偏移0
        mPaint.setPathEffect(new DashPathEffect(new float[] {15, 5}, 0));

        mPath = new Path();


        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.main);
        //从xml中获取参数
        startX = ta.getInteger(R.styleable.main_startX, 0);
        startY = ta.getInteger(R.styleable.main_startY, 0);

        LUX = ta.getFloat(R.styleable.main_rectLUX, 1);
        RDX = ta.getFloat(R.styleable.main_rectRDX, 1);
        endX = ta.getFloat(R.styleable.main_endX, 1);
        LUY = ta.getFloat(R.styleable.main_rectLUY, 1);
        RDY = ta.getFloat(R.styleable.main_rectRDY, 1);
        endY = ta.getFloat(R.styleable.main_endY, 1);
        ta.recycle();
    }


    @Override

    protected void onDraw(Canvas canvas) {
        // 获得视频的真实宽高
        int realWidth = MovieFragment.getVideoWidth();
        int realHeight = MovieFragment.getVideoHeight();
        // 实际视频view的高度计算
        int height = (int) (1.0 * VIDEO_WIDTH / realWidth * realHeight);
        int width = VIDEO_WIDTH;
        //除斜线左上角外,其他坐标由视频view的相对坐标转为实际坐标
        int rectLUX = VIDEO_MARGIN_LEFT + (int) (LUX * width);
        int rectRDX = VIDEO_MARGIN_LEFT + (int) (RDX * width);
        int rectEndX = VIDEO_MARGIN_LEFT + (int) (endX * width);
        int rectLUY = VIDEO_MARGIN_TOP + (int) (LUY * height);
        int rectRDY = VIDEO_MARGIN_TOP + (int) (RDY * height);
        int rectEndY = VIDEO_MARGIN_TOP + (int) (endY * height);
        // 斜线,如果不需要,将这段注释即可
        mPath.reset();
        mPath.moveTo(startX, startY);
        mPath.lineTo(rectEndX, rectEndY);
        canvas.drawPath(mPath, mPaint);
        // 矩形上横线
        mPath.reset();
        mPath.moveTo(rectLUX, rectLUY);
        mPath.lineTo(rectRDX, rectLUY);
        canvas.drawPath(mPath, mPaint);
        // 矩形右竖线
        mPath.reset();
        mPath.moveTo(rectRDX, rectLUY);
        mPath.lineTo(rectRDX, rectRDY);
        canvas.drawPath(mPath, mPaint);
        // 矩形下横线
        mPath.reset();
        mPath.moveTo(rectLUX, rectRDY);
        mPath.lineTo(rectRDX, rectRDY);
        canvas.drawPath(mPath, mPaint);
        // 矩形左竖线
        mPath.reset();
        mPath.moveTo(rectLUX, rectLUY);
        mPath.lineTo(rectLUX, rectRDY);
        canvas.drawPath(mPath, mPaint);

    }
}

对应xml中加载自定义view并设置对应参数:

<com.example.movie.DashLineView
    android:id="@+id/dashline"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:startX="300"
    app:startY="1050"
    app:endX="0.15"
    app:endY="0.9"
    app:rectLUX="0.1"
    app:rectLUY="0.5"
    app:rectRDX="0.2"
    />

在values文件夹下对各个参数(属性)进行定义:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="main">
        <attr name="startX" format="integer" />
        <attr name="startY" format="integer" />
        <attr name="endX" format="float" />
        <attr name="endY" format="float" />
        <attr name="rectLUX" format="float" />
        <attr name="rectLUY" format="float" />
        <attr name="rectRDX" format="float" />
        <attr name="rectRDY" format="float" />
    </declare-styleable>
</resources>

最终效果:

PS:由于获取视频尺寸需要prepared才给到,此时 DashLineView已经create和onMeasure,只能在onDraw时才能进行具体坐标的计算。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值