【问题标题】:Dragging an imageview to certain position将图像视图拖动到某个位置
【发布时间】:2015-07-09 05:18:46
【问题描述】:

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

我按照 android 网站上的说明进行操作,但无论我在哪里拖动 imageview,它总是在左上角结束。 (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);


}

【问题讨论】:

    标签: android drag-and-drop touch drag


    【解决方案1】:

    如果我理解你的意思,你的问题是除非你的手指在你的图像上方,否则你不会得到 MotionEvent.ACTION_MOVE。

    这是因为 DragListener 的概念是注册该侦听器的 View 接受事件。因此,您的布局中唯一注册到这些事件的视图是 chatHead,他只获取发生在他之上的事件。

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

      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 类型返回不同的值。

    【讨论】:

    • 感谢您的解释,它的工作原理!但是现在我又遇到了一个问题,因为我把整个屏幕都做成了可拖动的(容器=屏幕大小),屏幕上的按钮就不能再被触摸了。我试图通过在我长按图像视图时添加容器并在我放下时移除容器来解决这个问题。但我失败了。有什么建议吗??谢谢
    • 你的意思是“chatHead”按钮吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多