Android:拖放问题

时间:2011-02-22 22:52:27

标签: android drag-and-drop

我正在为一个班级写一个SMIL作曲家,我正在计划制作画布支持drap和drop,所以你可以随意放置图片和文字。我已经查看了示例并自己做了一些,但是当我去实现项目中的拖放时,它不起作用。以下是重要的主要代码:

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; 
            }//case image
        }//switch 
            return true; 
        }//onTouch 
    };//drag
}

这是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>
...

和image_add.xml:

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

当我单击作曲家上的添加按钮时,它成功地将图像添加到画布,当我触摸图像时,它会响应更大,从40x40到60x60就像它应该的那样。但是我的手指并没有跟在屏幕上,这就是我被卡住的地方。

任何输入都表示赞赏。

2 个答案:

答案 0 :(得分:14)

我研究了Android Launcher代码,看看它们是如何拖放的。我真的很喜欢他们的对象模型。他们做了什么,并且你可能考虑好处,是将处理拖放的责任移到ViewGroup中,其中所有可拖动的视图都在其中。触摸事件在那里而不是在您的视图中处理。

两个关键类:

DragLayer - 实现一个自定义ViewGroup,它可以协调屏幕上视图的移动。 Launcher DragLayer是FrameLayout的子类。

DragController - 此对象是执行大部分工作以支持拖放的控制器。

他们做的另一件事是在你拖动拖动的对象之前不移动实际视图。它看起来并不那样,因为在屏幕上,您会看到一个位图,该视图是在您的手指(或指针)移动时从视图构建的。

我构建了一个简单的例子并编写了它。见http://blahti.wordpress.com/2011/01/17/moving-views-part-2/ 该示例的源代码也在那里。

答案 1 :(得分:1)

如果您正在寻找预先制定的解决方案,那就是:

https://github.com/thquinn/DraggableGridView

这是一个自定义的ViewGroup,我认为它可能适合您的项目。祝你好运!