Android自定义控件移动及demo

来源:互联网 发布:自动聊天软件机器人 编辑:程序博客网 时间:2024/05/17 08:45


1、效果图如下,功能要求:十字岁手指的移动移动,且不超过圆形区域


2、自定义控件CrossView(圆+多边形十字)

public class CrossView extends View {    private float startX,startY;//十字架起点    private float width;//十字架宽度    private float centerX ;//圆心坐标x    private float centerY;//圆心坐标y    private float radius;//圆半径    private float crossCenterX;//以十字架中心为圆点的外切圆坐标x    private float crossCenterY;//以十字架中心为圆点的外切圆坐标y    public CrossView(Context context) {        super(context);        // TODO Auto-generated constructor stub    }    public CrossView(Context context, float centerX, float centerY, float radius, float width) {         super(context);        // TODO Auto-generated constructor stub        this.crossCenterX = centerX;        this.crossCenterY = centerY;        this.startX = crossCenterX - (width/2);        this.startY = crossCenterY - (width/2)-width;        this.centerX = centerX;        this.centerY = centerY;        this.width = width;        this.radius = radius;    }    public float getCenterX() {        return centerX;    }    public void setCenterX(float centerX) {        this.centerX = centerX;    }    public float getCenterY() {        return centerY;    }    public void setCenterY(float centerY) {        this.centerY = centerY;    }    public float getRadius() {        return radius;    }    public void setRadius(float radius) {        this.radius = radius;    }    public float getCrossCenterX() {        return crossCenterX;    }    public void setCrossCenterX(float crossCenterX) {        this.crossCenterX = crossCenterX;    }    public float getCrossCenterY() {        return crossCenterY;    }    public void setCrossCenterY(float crossCenterY) {        this.crossCenterY = crossCenterY;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawColor(Color.WHITE);        Paint paint = new Paint();        paint.setColor(Color.RED);        paint.setAntiAlias(true);        paint.setStrokeWidth(2);        paint.setStyle(Paint.Style.STROKE);        canvas.drawCircle(centerX, centerY, radius, paint);        paint.setStyle(Paint.Style.FILL);        this.startX = crossCenterX - (width/2);        this.startY = crossCenterY - (width/2)-width;        Path path = new Path();        path.moveTo(startX,startY);//起点        path.lineTo(startX+=width, startY);        path.lineTo(startX, startY+=width);        path.lineTo(startX+=width, startY);        path.lineTo(startX, startY+=width);        path.lineTo(startX-=width, startY);        path.lineTo(startX, startY+=width);        path.lineTo(startX-=width, startY);        path.lineTo(startX, startY-=width);        path.lineTo(startX-=width, startY);        path.lineTo(startX, startY-=width);        path.lineTo(startX+=width, startY);        path.close();        canvas.drawPath(path, paint);    }

3、在父布局中添加CrossView

 activity_drive_start = (Button) root.findViewById(R.id.activity_drive_start);        centerX = 100;        centerY = 60;        radius = 50;        width=10;        crossRadius = (3*width)/2;        crossView = new CrossView(context,centerX,centerY,radius,width);        relativeLayout.addView(crossView);        crossView.setOnTouchListener(this);


4、处理十字的移动

@Override    public boolean onTouch(View view, MotionEvent event) {        float X = event.getX();//注意多层嵌套时使用相对坐标        float Y = event.getY();        Log.d("zhu","x="+X+"=Y="+Y+"==");        crossCenterX = crossView.getCrossCenterX();        crossCenterY = crossView.getCrossCenterY();        if ((Tools.getDistance(centerX, centerY, X, Y)<=radius)) {//在圆圈内            if (Tools.getDistance(crossCenterX, crossCenterY, X, Y)<=(radius-crossRadius)) {//通过判断两个圆心的距离来判断十字不能出界                switch (event.getAction()) {                    case MotionEvent.ACTION_DOWN:                        break;                    case MotionEvent.ACTION_MOVE:                        if (Tools.getDistance(X, Y, centerX, centerY)<=(radius-crossRadius)) {//如果手指点击的范围在十字上就重绘十字以实现移动效果                            crossView.setCrossCenterX(X);                            crossView.setCrossCenterY(Y);                            crossView.invalidate();                        }                        break;                    default:                        break;                }            }        }        return true;    }

两点之间的距离

public static float getDistance(float x1,float y1,float x2,float y2){//坐标轴上两点之间的距离        float x=0,y=0;        x = x1>x2?(x1-x2):(x2-x1);        y = y1>y2?(y1-y2):(y2-y1);        return  (float) Math.sqrt(Math.pow(x, 2)+Math.pow(y, 2));    }

注意:处理坐标一定要使用相对坐标,不然横竖屏切换时控件绘制的地方会超出父布局,如果父布局是最外层布局就不影响。

横竖屏切换不重新绘制,保持原有状态,在配置文件中,相应的activity标签设置

 android:configChanges="orientation|screenSize"




附上demo下载地址
















0 0