实现多个控件之间画线连接并自由移动(线随控件动)

1.效果:

几个控件之间用线相连,在控件移动是线一直连接,随控件一起移动

2.自定义view中的代码



import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import java.util.ArrayList;


public class ImageViewDrawLine extends android.support.v7.widget.AppCompatImageView {
    private final int screenWidth;
    private final int screenHeight;
    private Paint paint;
    private int lastX;
    private int lastY;
    public ArrayList<ImageViewBean> imageViewBeans;

    private float startX;
    private float startY;
    private float stopX;
    private float stopY;
    private boolean isLian;
    private MyFramelayout fl;
    private LineBean lineBean;

    public void setPaint(Paint paint) {
        this.paint = paint;
    }

    public void setOnToDoListener(OnToDoListener onToDoListener) {
        this.onToDoListener = onToDoListener;
    }

    private OnToDoListener onToDoListener;


    interface OnToDoListener {
        void onLongClick(View v);

        void onTwoClick(View v);
    }

    public ImageViewDrawLine(Context context) {
        this(context, null);
    }

    public ImageViewDrawLine(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ImageViewDrawLine(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        DisplayMetrics dis = this.getResources().getDisplayMetrics();
        screenWidth = dis.widthPixels;
        screenHeight = dis.heightPixels;
        initPaint();
        imageViewBeans = new ArrayList<>();
        fl = (MyFramelayout) getParent();
    }

    private void initPaint() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(20);
        paint.setColor(Color.RED);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (!isLian) {
                    lastX = (int) event.getRawX();
                    lastY = (int) event.getRawY();
                    if (onToDoListener != null) {
                        long time = System.currentTimeMillis();
                        if (time - lastClickTime < 500) {
                            onToDoListener.onTwoClick(this);
                        }
                        lastClickTime = time;
                    }

                } else {

                    startX = event.getRawX();
                    startY = event.getRawY();
                    fl.isDraw = true;
                }
                break;

            case MotionEvent.ACTION_MOVE:
                MyFramelayout parent = (MyFramelayout) getParent();
                if (!isLian) {
                    int dx = (int) event.getRawX() - lastX;
                    int dy = (int) event.getRawY() - lastY;

                    int top = this.getTop() + dy;

                    int left = this.getLeft() + dx;

                    if (top <= 0) {
                        top = 0;
                    }
                    if (top >= screenHeight - this.getHeight()) {
                        top = screenHeight - this.getHeight();
                    }
                    if (left >= screenWidth - this.getWidth()) {
                        left = screenWidth - this.getWidth();
                    }

                    if (left <= 0) {
                        left = 0;
                    }
                    this.layout(left, top, left + this.getWidth(), top + this.getHeight());
                    lastX = (int) event.getRawX();
                    lastY = (int) event.getRawY();
                } else {
                    stopX = event.getRawX();
                    stopY = event.getRawY();
                    fl.drawLine(startX, startY, stopX, stopY);
                }
                break;
            case MotionEvent.ACTION_UP:
                stopX = event.getRawX();
                stopY = event.getRawY();
                if (!isLian) {


                } else {       


                    for (int i = 0; i < fl.getChildCount(); i++) {
                        ImageViewDrawLine childAt = (ImageViewDrawLine) fl.getChildAt(i);
                        if (stopY > childAt.getTop() && stopY < (childAt.getTop() + childAt.getHeight()) && stopX > childAt.getLeft()
                                && stopX < (childAt.getLeft() + childAt.getWidth()) && this.getId() != childAt.getId()) {

                            if (fl.arrayListLines.size() > 0) {
                                for (int j = 0; j < fl.arrayListLines.size(); j++) {
                                    LineBean lineBean = fl.arrayListLines.get(j);


                                    //满足同两个
                                    if ((lineBean.imageView.getId() == childAt.getId() && lineBean.imageView1.getId() == this.getId()) ||
                                            (lineBean.imageView.getId() == this.getId() && lineBean.imageView1.getId() == childAt.getId())) {
                                        if (lineBean.line > 4) {//设置一个控件与另一个相同控件最多的连接数
                                            Toast.makeText(getContext(), "不能连接更多了", Toast.LENGTH_SHORT).show();
                                            fl.isDraw = false;
                                            fl.invalidate();
                                            break;
                                        }
                                        lineBean.lineSt = lineBean.line + 1;
                                        lineBean.line = lineBean.lineSt;


                                        fl.isDraw = false;
                                        fl.invalidate();
                                        //添加跟自己相关的线的属性
                                        addImageBean(childAt, lineBean.line);
                                        break;
                                    } else if (j == fl.arrayListLines.size() - 1) {
                                        lineBean = new LineBean();
                                        lineBean.imageView = childAt;
                                        lineBean.imageView1 = this;
                                        lineBean.lineSt = 1;
                                        lineBean.line = 1;
                                        fl.arrayListLines.add(lineBean);


                          

                                        fl.isDraw = false;
                                        fl.invalidate();
                                        //添加跟自己相关的线的属性
                                        addImageBean(childAt, lineBean.line);
                                        break;
                                    }
                                }
                            } else {
                                lineBean = new LineBean();
                                lineBean.imageView = childAt;
                                lineBean.imageView1 = this;
                                lineBean.lineSt = 1;
                                lineBean.line = 1;
                                fl.arrayListLines.add(lineBean);

                                fl.isDraw = false;
                                fl.invalidate();
                                addImageBean(childAt, lineBean.line);
                            }
                            break;
                        } else {
                            if (i == fl.getChildCount() - 1) {
                                //销毁自己的线

                                fl.drawLine(startX, startY, startX, startY);
                            }
                        }
                    }
                }
                break;

            case MotionEvent.ACTION_CANCEL:
                fl.isDraw = false;
                fl.invalidate();
                break;
        }


        return true;

    }

    private void addImageBean(ImageViewDrawLine childAt1, int line) {
        if (line > 1) {
            for (int i = 0; i < this.imageViewBeans.size(); i++) {
                if (imageViewBeans.get(i).id == childAt1.getId()) {
                    imageViewBeans.get(i).lines++;
                }
            }
            for (int i = 0; i < childAt1.imageViewBeans.size(); i++) {
                if (childAt1.imageViewBeans.get(i).id == this.getId()) {
                    childAt1.imageViewBeans.get(i).lines++;
                }
            }

        } else if (line == 1) {
            ImageViewBean imageViewBean = new ImageViewBean();
            imageViewBean.id = childAt1.getId();
            this.imageViewBeans.add(imageViewBean);


            ImageViewBean imageViewBean1 = new ImageViewBean();
            imageViewBean1.id = this.getId();
            childAt1.imageViewBeans.add(imageViewBean1);
        }

    }

    private void update(float stopX, float stopY) {

    }

    public void setLian(boolean isLianl) {
        isLian = isLianl;
    }

    public void setParnt(MyFramelayout fl1) {
        fl = fl1;
    }

    private static long lastClickTime;

    public synchronized static boolean isFastClick() {
        long time = System.currentTimeMillis();
        if (time - lastClickTime < 500) {
            return true;
        }
        lastClickTime = time;
        return false;
    }
}
3.自定义viewGroup中的代码


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.FrameLayout;
import android.widget.ImageView;

import java.util.ArrayList;


public class MyFramelayout extends FrameLayout {
    private final int screenWidth;
    private final int screenHeight;
    private Paint paint;
    private int lastX;
    private int lastY;

    private float startX;
    private float startY;
    private float stopX;
    private float stopY;
    public boolean isDraw;
    public ArrayList<LineBean> arrayListLines;

    public MyFramelayout(@NonNull Context context) {
        this(context, null);
    }

    public MyFramelayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyFramelayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        DisplayMetrics dis = this.getResources().getDisplayMetrics();
        screenWidth = dis.widthPixels;
        screenHeight = dis.heightPixels;
        initPaint();


        arrayListLines = new ArrayList<>();
        setWillNotDraw(false);
    }

    private void initPaint() {
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5);
        paint.setColor(Color.RED);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.save();
        for (int i = 0; i < arrayListLines.size(); i++) {
            LineBean lineBean = arrayListLines.get(i);
            int lines = lineBean.line;
            if (lines == 1) {
                canvas.drawLine((lineBean.imageView1.getLeft() + lineBean.imageView1.getWidth() / 2),
                        (lineBean.imageView1.getTop() + lineBean.imageView1.getHeight() / 2),
                        (lineBean.imageView.getLeft() + lineBean.imageView.getWidth() / 2),
                        (lineBean.imageView.getTop() + lineBean.imageView.getHeight() / 2), paint);
            } else {

                for (int j = 0; j < lineBean.line; j++) {

                    canvas.drawLine((lineBean.imageView1.getLeft() + lineBean.imageView1.getWidth() * (j+1) / (lines+1)),
                            (lineBean.imageView1.getTop() + lineBean.imageView1.getHeight() * (j+1  ) / (lines+1)),
                            (lineBean.imageView.getLeft() + lineBean.imageView.getWidth() * (j+1 ) / (lines+1)),
                            (lineBean.imageView.getTop() + lineBean.imageView.getHeight() * (j+1  ) / (lines+1)), paint);
                }

            }

        }
        if (isDraw) {
            canvas.drawLine(startX, startY, stopX, stopY, paint);
        /*    canvas.drawCircle(startX, startY, 10f, paint);
            canvas.drawCircle(stopX, stopY, 10f, paint);*/
            canvas.restore();
        }

    }

    public void drawLine(int startX1, int startY1, int stopX1, int stopY1) {
        startX = startX1;
        startY = startY1;
        stopX = stopX1;
        stopY = stopY1;
        invalidate();
    }


    public void drawLine(float startX1, float startY1, float stopX1, float stopY1) {
        startX = startX1;
        startY = startY1;
        stopX = stopX1;
        stopY = stopY1;
        invalidate();
    }
}

4.使用方法

iv_l_1 = (ImageViewDrawLine) findViewById(R.id.iv_l_1);
iv_l_1.setParnt(fl);
其中fl为自定义viewgroup的实例对象;

iv_l_1.setOnToDoListener(this);

为控件设置双击事件

fl.isDraw = true;
isLian = !isLian;
iv_l_1.setLian(isLian);
控制是处于画线,还是移动.


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值