预览效果:
![](https://img-blog.csdnimg.cn/8b6a97b3c7f641c3868a5a635b767221.png)
涉及参数:
斜线起点坐标(斜线可以忽略) |
斜线终点坐标(斜线可以忽略) |
矩形左上角坐标 |
矩形右下角坐标 |
其中,前两个参数用于绘制预览效果中矩形上方的斜线,如果不需要可以移除。
本案例涉及视频外一个点指向视频内某块区域,因此参数略微复杂,除斜线起点坐标为实际坐标外,其他三个参数为百分比,例如矩形左上角坐标(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>
最终效果:
![](https://img-blog.csdnimg.cn/d621373ec42a4cc9a614d316af4d710b.png)
PS:由于获取视频尺寸需要prepared才给到,此时 DashLineView已经create和onMeasure,只能在onDraw时才能进行具体坐标的计算。