android - 如何绘制一条从拖放操作的源到目标的线?

标签 android drag-and-drop line draw

我已经实现了一个拖放系统,现在我想画一条从源到目的地的线。我怎样才能画出那条线?我已经使用了 View 类的扩展,但它不起作用。这是我的代码:

public class TempDDActivity extends Activity implements OnTouchListener {
    /** Called when the activity is first created. */
    private View selected_item = null;
    private int offset_x = 0;
    private int offset_y = 0;
    Boolean touchFlag=false;
    boolean dropFlag=false;
    LayoutParams imageParams;
    ImageView imageDrop,image1,image2;
    int crashX,crashY;
    Drawable dropDrawable,selectDrawable;
    Rect dropRect,selectRect;
    int topy,leftX,rightX,bottomY;

    int dropArray[];    

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.main);
        ViewGroup container = (ViewGroup) findViewById(R.id.container);
        imageDrop=(ImageView) findViewById(R.id.ImgDrop);       
        image1=(ImageView) findViewById(R.id.img);      
        image2=(ImageView) findViewById(R.id.img2);
        container.setOnTouchListener(new View.OnTouchListener() 
        {
            public boolean onTouch(View v, MotionEvent event) 
            {
                if(touchFlag==true)
                {
                    System.err.println("Display If  Part ::->"+touchFlag);
                    switch (event.getActionMasked()) 
                    {
                    case MotionEvent.ACTION_DOWN :

                         topy=imageDrop.getTop();
                         leftX=imageDrop.getLeft();
                         rightX=imageDrop.getRight();   
                         bottomY=imageDrop.getBottom();
                        System.err.println("Display Top-->"+topy);      
                        System.err.println("Display Left-->"+leftX);
                        System.err.println("Display Right-->"+rightX);
                        System.err.println("Display Bottom-->"+bottomY);                


                        //opRect.
                        break;
                    case MotionEvent.ACTION_MOVE:
                        crashX=(int) event.getX();
                        crashY=(int) event.getY();
                        System.err.println("Display Here X Value-->"+crashX);
                        System.err.println("Display Here Y Value-->"+crashY);

                        int x = (int) event.getX() - offset_x;
                        int y = (int) event.getY() - offset_y;                                          
                        //int w = getWindowManager().getDefaultDisplay().getWidth() - 100;
                        //int h = getWindowManager().getDefaultDisplay().getHeight() - 100;
                        int w = getWindowManager().getDefaultDisplay().getWidth() - 50;
                        int h = getWindowManager().getDefaultDisplay().getHeight() - 10;
                        if (x > w)
                            x = w;
                        if (y > h)
                            y = h;                      
                        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(new ViewGroup.MarginLayoutParams(  RelativeLayout.LayoutParams.WRAP_CONTENT,   RelativeLayout.LayoutParams.WRAP_CONTENT));
                        lp.setMargins(x, y, 0, 0);                  

                        //Drop Image Here                       
                        if(crashX > leftX && crashX < rightX && crashY > topy && crashY < bottomY )                     
                        {                           
                            Drawable temp=selected_item.getBackground();                            
                            imageDrop.setBackgroundDrawable(temp);
                            imageDrop.bringToFront();                           
                            dropFlag=true;
                            selected_item.setVisibility(View.INVISIBLE);
                        }
                        //Drop Image Here                       
                        selected_item.setLayoutParams(lp);
                        break;  
                    case MotionEvent.ACTION_UP:
                        //                      
                        touchFlag=false;
                        if(dropFlag==true)
                        {
                            dropFlag=false;
                        }
                        else
                        {
                            selected_item.setLayoutParams(imageParams);
                        }                       
                        break;
                    default:
                        break;
                    }
                }else
                {
                    System.err.println("Display Else Part ::->"+touchFlag);
                }               
                return true;
            }
        });

        image1.setOnTouchListener(this);
        image2.setOnTouchListener(this);
    }

    public boolean onTouch(View v, MotionEvent event) 
    {   
        switch (event.getActionMasked()) 
        {
        case MotionEvent.ACTION_DOWN:
            touchFlag=true;
            offset_x = (int) event.getX();
            offset_y = (int) event.getY();
            selected_item = v;
            imageParams=v.getLayoutParams();
            break;
        case MotionEvent.ACTION_UP:
            selected_item=null;
            touchFlag=false;
            break;
        default:
            break;
        }       
        return false;
    }
}

最佳答案

now I want to draw a line from source to destination

首先,您需要有一个用于实际绘制线条的自定义 View 。这将是包装 ImageViews 的布局,在您的情况下我认为它是 RelativeLayout。该类将类似于:

public class DragObserverLayout extends RelativeLayout {

    float startX, startY, stopX, stopY;
    private Paint mPaint = new Paint();
    private List<Rect> lines = new ArrayList<Rect>();

    public DragObserverLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(2.0f);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        final int count = lines.size();
        for (int i = 0; i < count; i++) {
            final Rect r = lines.get(i);
            canvas.drawLine(r.left, r.top, r.right, r.bottom, mPaint);
        }
    }

    public void addLine(Rect r) {
        lines.add(r);
        invalidate();
    }

}

然后在您执行拖动操作的容器的 OnTouchListener 中,您只需执行以下操作:

    final int[] location = new int[2];
    final DragObserverLayout container = (DragObserverLayout ) findViewById(R.id.container);       
    container.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            if(touchFlag==true) {
                switch (event.getActionMasked()) 
                {
                case MotionEvent.ACTION_DOWN :
                    //...
                    selected_item.getLocationOnScreen(location);
        container.startX = location[0];
        container.startY = location[1];  
                    break;
                case MotionEvent.ACTION_MOVE:
                  //...
                    selected_item.getLocationOnScreen(location);            
                    break;  
                case MotionEvent.ACTION_UP:
                    // ...
                    // .. the item was dragged on the target
                    if (selected_item.getVisibility() != View.VISIBLE) {
                        Rect r = new Rect();
                        r.left = (int) container.startX;
                        r.top = (int) container.startY;
                        imageDrop.getLocationInWindow(location);
                        r.right = location[0];
                        r.bottom = location[1];
                        container.addLine(r);
                    } 

这将从拖动的 ImageView 的初始位置( View 的左上角)到当前位置绘制一条直线 线,直到 ImageView 被“丢弃”。如果您愿意,您可以通过在 ImageViewsonTouch 方法中进行一些简单的计算来偏移起始线的位置以指向实际触摸的位置。这也适用于您有一个覆盖整个屏幕的全屏应用程序,否则您必须抵消 getLocationOnScreen() 的返回以考虑状态栏。如果您想在拖动操作完成后将该行保留在屏幕上,您需要将其存储在容器中。

关于android - 如何绘制一条从拖放操作的源到目标的线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15471038/

相关文章:

javascript - 限制 HTML5 中的可拖放行

cocoa - Cocoa中文件拖放的问题

java - 将一系列线段组合成多边形

java - 如何将txt文件中的数据复制到数组

java - 如何使用 BufferedReader 的 line.split 方法读取 Java 字符串?

android - 隐藏符号 `__cxa_begin_cleanup'

android - 如何使用带有垂直居中菜单导航和操作的扩展高度工具栏?

ios - 我可以通过从 Mac 拖放到 iOS 模拟器来接受文件吗?

android - 使用 MPAndroidChart 自定义 XAxis 标签

android - 在通知中使用大图标时出现 java.lang.NoClassDefFoundError