1

你好我正在一个Android游戏,允许用户拖动一些意见,并将他们放在另一个之上的每一个机构。Android视图拖放 - 只有匹配某个视图位置才接受视图拖放?

我有点新手,到目前为止我能够实现拖放操作,但是现在允许用户将视图放在屏幕的任何位置。

我想要做的就是将视图重置为原来的位置,如果它没有放在任何作为拖放区域的视图之上。请帮忙。

回答

2

这很晚!但是我很多天前成功地完成了它,现在我有时间分享我的解决方案,以防任何人感兴趣...我将解释我是如何在下面的简化示例中做到的,因为我的原始代码非常大附上如在我的说明性示例中所指示

enter image description here

上面有: 2图像视图(let1,let2)具有两个相对布局(let1Container,let2Container) 此外,还有两个空白图像视图(slot1,slot2),旨在充当拖放区域,与它们的容器(slot1Container,slot2Container)型的(相对布局) 沿着全部放置在RelativeLayout的整个屏幕,并命名(dragAreaRelativeLayout)

首先我们设置ontouchListener两个字母的观点:

let1_ImageView.setOnTouchListener(this); 
let2_ImageView.setOnTouchListener(this); 

,然后我们让我们的活动实现View.OnTouchListener,并提供类似下面的方法的实现:

@Override 
public boolean onTouch(View view, MotionEvent event) { 
    final int X = (int) event.getRawX(); 
    final int Y = (int) event.getRawY(); 

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

    if (parent != null) { 
     // detach the child from its parent 
     parent.removeView(view); 
    } 

    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(view.getLayoutParams()); 


    switch (event.getAction() & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: 


      layoutParams.leftMargin = X - 25; 
      layoutParams.topMargin = Y - 25; 
      layoutParams.rightMargin = -250; 
      layoutParams.bottomMargin = -250; 
      view.setLayoutParams(layoutParams); 
      viewRootLayout.addView(view); 

      break; 
     case MotionEvent.ACTION_UP: 

      adjustLocation(view, X, Y); 

      break; 
     case MotionEvent.ACTION_POINTER_DOWN: 
      break; 
     case MotionEvent.ACTION_POINTER_UP: 

      break; 
     case MotionEvent.ACTION_MOVE: 

      viewRootLayout = (ViewGroup) findViewById(R.id.dragAreaRelativeLayout); 
      layoutParams.leftMargin = X - 25; 
      layoutParams.topMargin = Y - 25; 
      layoutParams.rightMargin = -250; 
      layoutParams.bottomMargin = -250; 
      view.setLayoutParams(layoutParams); 
      viewRootLayout.addView(view); 
      break; 
    } 
    viewRootLayout.invalidate(); 
    return true; 
} 

以前的代码允许用户拖动字母到屏幕上的任何位置,并调用我命名为adjustLocation(view, X, Y);的方法,一旦拖动的图像被释放MotionEvent.ACTION_UP此方法将检查拖动的图像是否放置在其中一个插槽中并且如果没有正确放置它将把它放回原来的位置,在这里是如何工作的?

void adjustLocation(View view, int X, int Y) { 
    RelativeLayout.LayoutParams slot1_LayoutParams = (RelativeLayout.LayoutParams) slot1.getLayoutParams(); 
    RelativeLayout.LayoutParams slot2_LayoutParams = (RelativeLayout.LayoutParams) slot2.getLayoutParams(); 
    int[] slot1_viewLocation = new int[2]; 
    int[] slot2_viewLocation = new int[2]; 
    slot1.getLocationInWindow(slot1_viewLocation); 
    slot2.getLocationInWindow(slot1_viewLocation); 

    //detect drop zone boundaries and check if the view is dropped at relative location 
    if (Y >= slot1_viewLocation[1] && (Y < (slot1_viewLocation[1] + slot1.getHeight()))) { 
     //first we check if it is placed over SLOT 1 
     if ((X >= slot1_viewLocation[0]) && (X < (slot1_viewLocation[0] + slot1.getWidth()))) { 
      view.setLayoutParams(slot1_LayoutParams); 
      viewRootLayout = (ViewGroup) findViewById(R.id.slot1Container); 
      viewRootLayout.addView(view); 
     } 
    } else if (Y >= slot2_viewLocation[1] && (Y < (slot2_viewLocation[1] + slot2.getHeight()))) { 
     //then we check if it is placed over SLOT 2 
     if ((X >= slot2_viewLocation[0]) && (X < (slot2_viewLocation[0] + slot2.getWidth()))) { 
      view.setLayoutParams(slot2_LayoutParams); 
      viewRootLayout = (ViewGroup) findViewById(R.id.let2SlotRelativeLayout); 
      viewRootLayout.addView(view); 
     } 
    } else { 
     // if the dragged image wasn't dropped neither in slot 1 or slot 2 (drop zaone 1,2) 
     // we send it back to its location 
     resetViewLocation(view); 
    } 
} 

现在就让我们送小姐放置图像回它是从哪里来的,做所以我设法跟踪veiws原始LayoutParamsonCreate()

let1_LayoutParams = (RelativeLayout.LayoutParams) let1.getLayoutParams(); 
let2_LayoutParams = (RelativeLayout.LayoutParams) let2.getLayoutParams(); 

,并终于在这里是我们如何重置其位置到原来的位置:

void resetViewLocation(View view) { 
    ViewGroup viewOriginalLayout = null; 
    RelativeLayout.LayoutParams viewOriginalParams = null; 
    ViewGroup parent = (ViewGroup) view.getParent(); 

    if (parent != null) { 
     // detach the child from current parent 
     parent.removeView(view); 
    } 

    int viewId = view.getId(); 

    if (viewId == let1.getId()) { 
     viewOriginalParams = let1_LayoutParams; 
     viewOriginalLayout = (ViewGroup) findViewById(R.id.let1Container); 
    } else if (viewId == let2.getId()) { 
     viewOriginalParams = let2_LayoutParams; 
     viewOriginalLayout = (ViewGroup) findViewById(R.id.let2Container); 
    } 

    view.setLayoutParams(viewOriginalParams); 
    viewOriginalLayout.addView(view); 
    viewOriginalLayout.invalidate(); 
} 

请注意的是,包括了所有片段没有经过测试我只是写了他们此刻的我张贴这个答案。然而,这项技术对我来说很有魅力,而且这个代码也应该可以工作,我会让你去尝试,如果需要,我会很乐意提供任何帮助。

P.S.我不知道这是否是最好的方法,但我已经等待并希望继续前进,因此任何想法都可以提高代码或技术的性能。