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.我不知道這是否是最好的方法,但我已經等待並希望繼續前進,因此任何想法都可以提高代碼或技術的性能。