1.自定义View的实现
继承自View 重写 onDraw方法
public class MyLine extends View { Paint mPaint; int startX; int startY; int endX; int endY; public static Point mPoint1; public static Point mPoint2; public MyLine(Context context) { super(context); initPaint(); } public MyLine(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initPaint(); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyLine); startX = ta.getInteger(R.styleable.MyLine_startX,100); startY = ta.getInteger(R.styleable.MyLine_startY, 100); endX = ta.getInteger(R.styleable.MyLine_endX,100); endY = ta.getInteger(R.styleable.MyLine_endY, 100); mPoint1 = new Point(startX,startY); mPoint2 = new Point(endX,endY); } public static Point getPoint1() { return mPoint1; } public static Point getPoint2() { return mPoint2; } public MyLine(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initPaint(); } public MyLine(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); initPaint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawLine(startX,startY,endX,endY,mPaint); } public void initPaint(){ mPaint = new Paint(); mPaint.setColor(Color.BLUE); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(10); } }
2.自定义View 自定义属性
在values文件夹下创建attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyPoint"> <attr name="X" format="integer"/> <attr name="Y" format="integer"/> </declare-styleable> <declare-styleable name="MyLine"> <attr name="startX" format="integer"/> <attr name="endX" format="integer"/> <attr name="startY" format="integer"/> <attr name="endY" format="integer"/> </declare-styleable> </resources>
获取属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyLine); startX = ta.getInteger(R.styleable.MyLine_startX,100); startY = ta.getInteger(R.styleable.MyLine_startY, 100); endX = ta.getInteger(R.styleable.MyLine_endX,100); endY = ta.getInteger(R.styleable.MyLine_endY, 100);
3.添加点击事件
在自定义view的类里添加触摸事件和点击事件的接口
@Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); int action = event.getAction(); switch (action) { case MotionEvent.ACTION_UP: if (x + getLeft() < getRight() && y + getTop() < getBottom()) { mPoint = new Point(x,y); mViewClick.onClick(x,y,mOnViewClick); } break; } return true; } public void setOnViewClick(onViewClick click) { this.mViewClick = click; } public interface onViewClick { void onClick(int scrollX, int scrollY,onViewClick onViewClick); } onViewClick mOnViewClick = new onViewClick() { @Override public void onClick(int scrollX, int scrollY, onViewClick onViewClick) { sX = scrollX; sY = scrollY; invalidate();// 重绘 会重新调用onDraw方法 } };
mMyPoint = findViewById(R.id.point); mMyPoint.setOnViewClick(mMyPoint.mOnViewClick);
4.绘制虚线
mPaint.setPathEffect(new DashPathEffect(new float[] {30, 5}, 0)); 其中30 表示实线的长度 5代表空白的长度
5.已知直线和直线外一点,获取垂足坐标
// // private Point getFoot(Point p1,Point p2,Point p3){ // Point foot=new Point(); // // float dx=p1.x-p2.x; // float dy=p1.y-p2.y; // Log.e("TAG",dx+" "+dy); // float u=(p3.x-p1.x)*dx+(p3.y-p1.y)*dy; // u/=dx*dx+dy*dy; // // foot.x=(int)(p1.x+u*dx); // foot.y=(int)(p1.y+u*dy); // // float d=Math.abs((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); // float d1=Math.abs((p1.x-foot.x)*(p1.x-foot.x)+(p1.y-foot.y)*(p1.y-foot.y)); // float d2=Math.abs((p2.x-foot.x)*(p2.x-foot.x)+(p2.y-foot.y)*(p2.y-foot.y)); // // if(d1>d||d2>d){ // if (d1>d2) return p2; // else return p1; // } // // return foot; // } private Point getFoot(Point p1,Point p2,Point p3){ Point foot=new Point(); float dx=p1.x-p2.x; float dy=p1.y-p2.y; float u=(p3.x-p1.x)*dx+(p3.y-p1.y)*dy; u/=dx*dx+dy*dy; foot.x=(int)(p1.x+u*dx); foot.y=(int)(p1.y+u*dy); return foot; }