我在我的应用中捕捉拖动事件,并且不想为可放置的容器设置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,直到用户传递到其他屏幕。
图像视图是动态的,取决于选择的文件夹图像。
@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);
}
}
}