如何抓住getX&在DragListener中的视图之外的getY

时间:2013-11-29 11:00:16

标签: android events view touch drag

我在我的应用中捕捉拖动事件,并且不想为可放置的容器设置gridLayout。
所以,我有很多观点,片段和膨胀,并且想要得到ACTION_DRAG_ENDED的X和getY,但是当你把对象放在他的容器之外时,不知道怎么回事。 那么,有没有办法让整个屏幕上的coordonates,独立于什么容器是圣经,没有创建一个gridlayout for drop?只是getcoordonates

我有一个baseAdapter用于拖动对象:

public View getView(int pos, View convertView, ViewGroup parent) {

        View retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null);
        Drawable dr = null;

         try {
            dr = Drawable.createFromStream(getActivity().getAssets().open(listItems.get(pos).thumbPath + "/" + listItems.get(pos).name ), null) ;
        } catch (IOException e) {
            e.printStackTrace();
        }


        ImageView imgV = (ImageView) retval.findViewById(R.id.thumbImg);
        //imgV.setImageResource(R.drawable.icon_masks);
        if(dr != null){ 
            imgV.setImageDrawable(dr) ;
            imgV.setOnClickListener(this);
            imgV.setTag(listItems.get(pos).name);

            if(listType != 1)
                imgV.setOnTouchListener(new HappyTouchListener());
        }

        return retval;
    }

我的onTouch和Drag Listener:

public class HappyTouchListener implements OnTouchListener {

    public boolean onTouch(View view, MotionEvent motionEvent) {        

        // get pointer index from the event object
        int pointerIndex = motionEvent.getActionIndex();

        PointF f = new PointF();
        f.x = motionEvent.getX(pointerIndex);
        f.y = motionEvent.getY(pointerIndex);

        float eventX = motionEvent.getX();
        float eventY = motionEvent.getY();

        Log.d("MyTouch", "Point " + f.x);

            switch(motionEvent.getAction()){
                case MotionEvent.ACTION_DOWN :
                    Log.d("MyTouch", "Ca bouge! Action" + f.x + " / " + f.y );
                    ClipData data = ClipData.newPlainText("", "");
                    DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
                    view.startDrag(data, shadowBuilder, view, 0);
                    view.setOnDragListener(new HappyDragListener() );

                    return true;

                case MotionEvent.ACTION_UP :
                    Log.d("MyTouch", "Action Up! " + eventX + " / " + eventY );
                    break; 
                case MotionEvent.ACTION_MOVE :
                    Log.d("MyTouch", "Action move! " + eventX + " / " + eventY );
                    break;          

                default:
                     Log.d("MyTouch", "false");
                    return false;
            }


            return false;         
      }

    /**
     * Listener onDrag
     */
    private class HappyDragListener implements OnDragListener {

        @Override
        public boolean onDrag(View v, DragEvent event) {
             Log.d("onDrag", "onDrag Init");


             switch (event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                     //Log.d("onDrag", "onDrag Started");                   
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
                     //Log.d("onDrag", "onDrag Entered");                                       

                    break;
                case DragEvent.ACTION_DRAG_EXITED:
                     Log.d("onDrag", "onDrag Exited "   + event.getX() + " | " + event.getY()); 
                           // this is a personal listener for receive infos
                     listener.onTouchIt(v, event);                       
                    // This Is It!
                    break;
                case DragEvent.ACTION_DROP:
                    //handle the dragged view being dropped over a drop view
                     Log.d("onDrag", "onDrag Drop : "  + event.getX() + " | " + event.getY() );                 
                    break;
                case DragEvent.ACTION_DRAG_ENDED:
                     Log.d("onDrag", "onDrag Ended : " + event.getX() + " | " + event.getY() );                          
                    break;
                default:
                     //Log.d("onDrag", "onDrag Default do nothing");                                        
                    break;
            }

            return true;
        }


    }

}

所以我编辑分享我的经验,我已经完成了它,放到一个不是视图的父级的容器(ImageView在listView中)并且我有很多视图是非常复杂的,片段,并希望在屏幕上保持精确的坐标,并在拖动的视图上保持onTouch,直到用户传递到其他屏幕。
图像视图是动态的,取决于选择的文件夹图像。

所以诀窍是像一个自然的机器人拖动和拖动放下一个容器,一旦它被拖动,就在这个视图上释放onTouch监听器,删除视图和他的监听器,并在容器上可拖动的同一个xy和位图上构建一个可拖动视图。登记/> 如果它可以引起兴趣或帮助某人,或者有人认为这样做不好并且有更好的解决方案,那么感兴趣;)

    @Override
    public View getView(int pos, View convertView, ViewGroup parent) {

        View retval = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewitem, null);

        ImageView imgV = (ImageView) retval.findViewById(R.id.thumbImg);
        imgV.setOnTouchListener(new MyHappyTouchListener() );
    }






        public class HappyDragListener implements OnDragListener {

            FragmentListener listener;

            @Override
            public boolean onDrag(View v, DragEvent event) {
                //handle the dragged view being dropped over a drop view
                 View view = (View) event.getLocalState();

                         switch (event.getAction()) {
                            case DragEvent.ACTION_DROP:
                                 int x = (int) event.getX(); int y = (int) event.getY();
                                 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
                                                                    FrameLayout.LayoutParams.FILL_PARENT, 
                                                                    Gravity.TOP);                    
                                 lp.leftMargin = (int) event.getX();
                                 lp.topMargin = (int) event.getY();
                                 lp.rightMargin = 0;
                         lp.bottomMargin = 0;

                        ViewGroup owner = (ViewGroup) view.getParent();

                        owner.removeView(view);
                        FrameLayout container = (FrameLayout) v;
                        container.addView(view);
                        container.setLayoutParams(lp);            
                        view.setVisibility(View.VISIBLE);
                        //Fire event to MainActivity
                        listener =  (FragmentListener) v.getContext() ;
                        listener.sendMove(view, event);

                        break;
                    default:
                        break;
                }

            return true;
            }   



        public class MyActivity extends Activity implements FragmentListener{

            /*
             * Renvoi de la View et de l event via le dragListener<br/>
             * La vue container ayant ete enregistree, le container recoi l event ACTION_DROP 
             * avec l event associe  
             * (non-Javadoc)
             * @see com.sezn.fragments.FragmentListener#sendMove(android.view.View, android.view.DragEvent)
             */
            @Override
            public void sendMove(View v, DragEvent event) {
            v.setOnTouchListener(null);

                v.setVisibility(View.GONE);
                putThisOnScreen(v, event);          
            }

            /**
             * Methode pour palier au drag drop, supprime la vue draggee et positionne une nouvelle DragItView en X Y<br/> 
             * La DragIt View gere le drag du nouvel element
             * @param v
             * @param event
             */
            public void putThisOnScreen(View v, DragEvent event) {

                Bitmap bm = getBitmapFromMyView(v);                 
                DragItView vue = new DragItView(Activity.this, (int)event.getX(), (int)event.getY(), bm);
                findViewById(R.id.imageBigView).addView(vue);
                viewsAdded.add(vue);    
            }






            public DragItView(Context context, int X, int Y, Bitmap bm) {
                this(context);
                this.setImageBitmap(bm);

                FrameLayout.LayoutParams layout = (LayoutParams) this.getLayoutParams();    
                layout.leftMargin = X - layout.width/2;
                layout.topMargin = Y - layout.height/2;
                Log.d(TAG, "adding view at : " + layout.leftMargin + ", " + layout.topMargin );
                this.setLayoutParams(layout);
            }

            public boolean onTouch(View v, MotionEvent event) {
                FrameLayout.LayoutParams layout = (LayoutParams) v.getLayoutParams();
                if (event.getAction()==MotionEvent.ACTION_DOWN) {
                    localX = (int)event.getX();
                    localY = (int)event.getY();
                    Log.d(TAG, "View : " + v.getId() );
                    v.bringToFront();
                    return true;
                }
                if (event.getAction()==MotionEvent.ACTION_MOVE) {
                    layout.leftMargin = (int) event.getRawX() - localX;         
                    layout.topMargin = (int) event.getRawY() - v.getHeight()/2 - localY;
                }
                if (event.getAction()==MotionEvent.ACTION_UP) {
                }
                v.setLayoutParams(layout);
                return true;
            }

这是我的整个DragItView处理元素被删除后移动

 public class DragItView extends ImageView implements OnTouchListener {

    private Context context;
    private View thisView;  
    private int localX=0; private int oldX=0;
    private int localY=0;
    ScaleGestureDetector mGestureDetector;

    final Handler handler = new Handler(); 

    /**
     *  Au LongClick, on supprime la vue 
     */
    Runnable mLongPressed = new Runnable() { 
        public void run() { 

            Vibrator v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
             v.vibrate(50);

            thisView.setOnTouchListener(null);
            try{
                ((ViewManager)thisView.getParent()).removeView(thisView);
            }catch(Exception e){ Log.d(TAG, "Exception " + e.getMessage() ); }
        }   
    };

    public DragItView(Context context) {
        super(context);
        this.context = context;
        // ATTENTION ne pas oublier le Gravity !! 
        this.setLayoutParams( new FrameLayout.LayoutParams(150, 150, Gravity.TOP));
        setOnTouchListener(this);
        setLongClickable(true);
        //mGestureDetector = new ScaleGestureDetector(context, new ScaleGesture());     
    }



    /**
     * Nouvelle DragItView avec un Bitmap
     * @param context
     * @param X
     * @param Y
     * @param bm
     */
    public DragItView(Context context, int X, int Y, Bitmap bm, boolean conserveW) {
        this(context);
        this.setImageBitmap(bm);

        FrameLayout.LayoutParams layout = (LayoutParams) this.getLayoutParams();    
        layout.leftMargin = X - layout.width/2;
        layout.topMargin = Y - layout.height/2;
        Log.d(TAG, "adding view at : " + layout.leftMargin + ", " + layout.topMargin );
        if(conserveW){
            layout.width = bm.getWidth();
            layout.height= bm.getHeight();
        }else{
            layout.width = bm.getWidth()/2;
            layout.height= bm.getHeight()/2;
        }

        this.setLayoutParams(layout);
        mGestureDetector = new ScaleGestureDetector(context, new ScaleGesture());
    }

    public boolean onTouch(View v, MotionEvent event) {
        this.thisView = v;      

        FrameLayout.LayoutParams layout = (LayoutParams) v.getLayoutParams();
        if (event.getAction()==MotionEvent.ACTION_DOWN) {
            localX = (int)event.getX();
            localY = (int)event.getY();
            oldX= localX;
             handler.postDelayed(mLongPressed, 2000);
            v.bringToFront();
            return true;
        }
        if (event.getAction()==MotionEvent.ACTION_MOVE) {
            layout.leftMargin = (int) event.getRawX() - localX;         
            layout.topMargin = (int) event.getRawY()  - localY;
            if(oldX!= (int) event.getRawX() ){
                oldX= (int) event.getRawX()  ;
                // Vire le handler longPressed
                handler.removeCallbacks(mLongPressed);
            }else
                handler.postDelayed(mLongPressed, 1200);

 //         Log.d(TAG, "Moving : " + localX + " " + localY);
        }
        if (event.getAction()==MotionEvent.ACTION_UP) {
            // Vire le handler longPressed
            handler.removeCallbacks(mLongPressed);
        }
        v.setLayoutParams(layout);

        if (mGestureDetector.onTouchEvent(event)){
            return false;
        }
        return false;
    }

    /*******************************/
    private class ScaleGesture extends SimpleOnScaleGestureListener {

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            return super.onScaleBegin(detector);
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            Log.d(TAG, "onScale " + detector.getScaleFactor() );        
            float scale =  detector.getScaleFactor() ;

            thisView.setScaleX(scale);
            thisView.setScaleY(scale);
            invalidate();
            return super.onScale(detector);
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            Log.d(TAG, "onScaleEnd");           
            super.onScaleEnd(detector);
        }
    }
 }

0 个答案:

没有答案