我正在为一个班级编写一个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"/>
当我单击作曲家上的添加按钮时,它成功地将图像添加到画布上,当我触摸图像时,它会响应变大,从40×40到60×60就像它应该的那样.但是我的手指并没跟在屏幕上,而那就是我被卡住的地方.
任何输入都表示赞赏.
解决方法
我研究了Android Launcher代码,看看它们是如何拖放的.我真的很喜欢他们的对象模型.他们做了什么,并且可能对你有好处的考虑,是将处理拖放的责任转移到ViewGroup中,其中所有可拖动的视图都在其中.触摸事件在那里而不是在您的视图中处理.
两个关键类:
DragLayer – 实现一个自定义ViewGroup,它可以协调屏幕上视图的移动. Launcher DragLayer是FrameLayout的子类.
DragController – 该对象是执行大部分工作以支持拖放的控制器.
他们做的另一件事是在你拖动拖动的对象之前不移动实际视图.它看起来并不那样,因为在屏幕上你会看到一个位图,当你的手指(或指针)移动时,视图会随着视图的移动而构建.
我构建了一个简单的例子并编写了它.见http://blahti.wordpress.com/2011/01/17/moving-views-part-2/该示例的源代码也在那里.