将imageview拖动到某个位置

时间:2015-07-09 05:18:47

标签: android drag-and-drop touch drag

我正在尝试创建一个可拖动的imageView(" chatHead"在代码中,有点像Facebook的聊天主管)

我按照Android网站上的说明操作,但是无论我拖动图像视图,它总是在左上角结束。 (x,y坐标为(0,0)〜(90,90))

后来我发现问题是案例:当我的触摸在imageView位置周围时,MotionEvent.ACTION_MOVE仅

当我离imageView稍微远一点时,不再输入 ACTION_MOVE 。而是执行 DragEvent.ACTION_DRAG_EXIT 的情况。

有人能告诉我如何扩展ACTION_MOVE的执行区域或问题是什么。我想在屏幕上的任何位置找到imageView。
(你可能只关注 onDragListener ,MyDragShadowBuilder是一个自定义的扩展DragShawdowBuilder,而onLongClickListener只是为了触发拖动)

如果关闭应用程序,如何保持imageView?

public class ChatHead extends Service {

private WindowManager windowManager;
private ImageView chatHead;
private WindowManager.LayoutParams params;
private final String CHAT_TAG ="CHAT";
private int cor_x = 0;
private int cor_y = 0;



@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("Not yet implemented");
}

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override public void onCreate() {
    super.onCreate();
    ImageView image = new ImageView(this);
    Log.d("", "created");
    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    chatHead = new ImageView(this);
    chatHead.setTag(CHAT_TAG);
    chatHead.setImageResource(R.drawable.chat_icon);

     params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 300;
    params.y = 300;



    chatHead.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {



                    ClipData.Item item = new ClipData.Item(v.getTag().toString());


                    String[] mimeTypes =  {ClipDescription.MIMETYPE_TEXT_PLAIN};
                    ClipData dragData = new ClipData(v.getTag().toString(), mimeTypes,item);

                    View.DragShadowBuilder myShadow = new MyDragShadowBuilder(chatHead);

                    // Starts the drag

                    v.startDrag(dragData,  // the data to be dragged
                            myShadow,      // the drag shadow builder
                            null,          // no need to use local data
                            0              // flags (not currently used, set to 0)
                    );

            return false;}

    });



    chatHead.setOnDragListener(new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {

            //cor_x = ((int) chatHead.getX());
            //cor_y = ((int) chatHead.getY());

            switch (event.getAction()){
                case DragEvent.ACTION_DRAG_ENTERED : { Log.d("", "x:"+ event.getX()+"y:"+event.getY());break;}
                case DragEvent.ACTION_DRAG_STARTED : { Log.d("", "x:"+ event.getX()+"  y:"+event.getY());break;}

                case MotionEvent.ACTION_MOVE:  {
                    cor_x = ((int) event.getX());
                    cor_y = ((int) event.getX());
                    Log.d("", "x:"+ cor_x+"  y:"+cor_y);
                    break;}
                case DragEvent.ACTION_DRAG_EXITED:{
                    Log.d("", "x:"+ cor_x+"  y:"+cor_y);
                    break;
                }


                case DragEvent.ACTION_DRAG_ENDED   :  {
                    if(windowManager!=null && params!=null){
                        params.x = cor_x;
                        params.y = cor_y;
                        Log.d("", "x:"+ cor_x+"  y:"+cor_y);
                        windowManager.removeView(chatHead);
                        windowManager.addView(chatHead, params);
                    }

                    return false;
                }

            }


            return false;
        }
    });

    windowManager.addView(chatHead, params);


}

1 个答案:

答案 0 :(得分:0)

如果我明白你的意思,你的问题就是你没有得到MotionEvent.ACTION_MOVE,除非你的手指在你的图像之上。

好吧那是因为DragListener的概念是注册那个监听器的View,接受事件。因此,您的布局中唯一注册到这些事件的视图是chatHead,并且他只获取发生在他上方的事件。

因此,如果您想要获取布局中的所有事件,则必须注册占据整个屏幕空间的视图。所以最快的解决方案是用包含整个屏幕的容器包装视图,然后将chatHead注册到DragListener。 Somethong喜欢:

  windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    RelativeLayout container = new RelativeLayout(this);


    params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    chatHead = new ImageView(this);
    chatHead.setTag(CHAT_TAG);
    chatHead.setImageResource(R.drawable.chat_icon);

    RelativeLayout.LayoutParams chatHeadParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    chatHeadParams.addRule(Gravity.TOP | Gravity.LEFT)  ;
    chatHeadParams.leftMargin = 300;
    chatHeadParams.topMargin = 300;

    container.addView(chatHead, chatHeadParams);
    windowManager.addView(container, params);

改变界限:

    chatHead.setOnLongClickListener(new View.OnLongClickListener() {

为:

    container.setOnLongClickListener(new View.OnLongClickListener() {

您还可以调整其他内容,因为DragEvent event.getX()和event.getX()将根据View本身和DragEvent.Action类型返回不同的值。