开发者

Android: Drag and Drop issue

开发者 https://www.devze.com 2023-02-12 23:43 出处:网络
I\'m writing a SMIL composer for a class, and I was planning on making the canvas support drap and drop, so you can place pictures and text however you want. I\'ve looked through examples and did a fe

I'm writing a SMIL composer for a class, and I was planning on making the canvas support drap and drop, so you can place pictures and text however you want. I've looked through examples and did a few on my own, but when I go to implement the drag and drop in my project, it doesn't work. Here is the main code that matters:

public class ComposerActivity extends Activity {
    /** Called when the activity is first created. */

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.composer);

    Button add = (Button)findViewById(R.id.addBtn);
    ...

    add.setOnClickListener(mClick);
    ...
}

OnClickListener mClick = new OnClickListener() {
    @Override
    public void onClick(View v){        
        if(v.getId() == R.id.addBtn)
        {
            FrameLayout fl = (FrameLayout)findViewById(R.id.Canvas); 
            LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
            View itemView = inflater.inflate(R.layout.image_add, null);

            View image = (View)itemView.findViewById(R.id.image);   
            image.setBackgroundResource(R.drawable.icon); 

            fl.addView(itemView, new FrameLayout.LayoutParams(40, 40));  

            image.setOnTouchListener(drag);
        }
        ...

OnTouchListener drag = new OnTouchListener(){
    @Override 
    public boolean onTouch(View v, MotionEvent event){ 
        FrameLayout.LayoutParams par = (LayoutParams) v.getLayoutParams(); 
        switch(v.getId()){//What is being touched 
            case R.id.image:{//Which action is being taken 
                switch(event.getAction()){ 
                    case MotionEvent.ACTION_MOVE:{  
                        par.topMargin = (int)event.getRawY() - (v.getHeight()); 
                        par.leftMargin = (int)event.getRawX() - (v.getWidth()/2); 
                        v.setLayoutParams(par); 
                        break; 
                    }//inner case MOVE 
                    case MotionEvent.ACTION_UP:{ 
                        par.height = 40; 
                        par.width = 40; 
                        par.topMargin = (int)event.getRawY() - (v.getHeight()); 
                        par.leftMargin = (int)event.getRawX() - (v.getWidth()/2); 
                        v.setLayoutParams(par); 
                        break; 
                    }//inner case UP 
                    case MotionEvent.ACTION_DOWN:{ 
                        par.height = 60; 
                        par.width = 60; 
                        v.setLayoutParams(par); 
                        break; 
                    }//inner case UP 
                }//inner switch 
                break; 
         开发者_JAVA百科   }//case image
        }//switch 
            return true; 
        }//onTouch 
    };//drag
}

Here is the composer.xml:

...
<FrameLayout android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_below="@+id/TopBar" 
    android:layout_above="@+id/addBtn" 
    android:id="@+id/Canvas"
    android:layout_gravity="top">

</FrameLayout>
...

and the image_add.xml:

<View android:id="@+id/image" 
        android:layout_gravity="top"
        xmlns:android="http://schemas.android.com/apk/res/android"/> 

When I click the add button on my composer, it successfully adds the image to the canvas, and when I touch the image, it responds by getting bigger, from 40x40 to 60x60 like it should. But it doesn't follow my finger across the screen, and thats where I'm stuck.

Any input is appreciated.


I studied the Android Launcher code to see how they did drag and drop. I really like their object model. What they did, and it might be good for you to consider, is move the responsibility for handling drag and drop out to the ViewGroup in which all the draggable views are inside of. Touch events get handled there rather than in your views.

Two of the key classes:

DragLayer – implements a custom ViewGroup, which coordinates movement of views on the screen. The Launcher DragLayer is a subclass of FrameLayout.

DragController – This object is the controller that does most of the work to support dragging and dropping.

The other thing they do is not move the actual view until you drop the object you are dragging. It does not look that way though because on the screen you see a bitmap constructed from the view moving as your finger (or pointer) moves.

I built a simple example and wrote it up. See http://blahti.wordpress.com/2011/01/17/moving-views-part-2/ Source code of the example is there too.


If you're looking for a pre-made solution, there's this:

https://github.com/thquinn/DraggableGridView

It's a custom ViewGroup I put together that seems like it might be suited to your project. Good luck!

0

精彩评论

暂无评论...
验证码 换一张
取 消