2012-06-04 5 views
1

저는 RelativeLayout에 4 개의 자식 FrameLayouts이있는 앱을 만들고 있습니다. 각 FrameLayout에는 이미지 뷰 세트가 있고 내부 뷰에는 자체 동작이 있습니다. 나는 onTouchListener을 구현하면서 FrameLayouts에 드래그 앤 드롭을 구현하려고 시도하고 있는데, 이는 this tutorial에서 발견되었습니다. 하지만 불행히도 드래그 앤 드롭은 제대로 작동하지 않으며 아무 일도 일어나지 않습니다.Android : onTouchListener가 제대로 작동하지 않습니다.

드래그 앤 드롭을 올바르게 구현하는 방법에 대한 의견이 있으십니까? 나는 무엇을 놓치고 있습니까? 여기에 자바 코드 인 main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="@drawable/pinecropped" 
    android:orientation="vertical" > 

    <FrameLayout 
     android:id="@+id/cardNumber1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="50dp" 
     android:layout_marginTop="60dp" > 

     <include layout="@layout/card" /> 
    </FrameLayout> 

    <FrameLayout 
     android:id="@+id/cardNumber2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/cardNumber1" 
     android:layout_marginLeft="50dp" 
     android:layout_marginTop="100dp" > 

     <include layout="@layout/card" /> 
    </FrameLayout> 

    <FrameLayout 
     android:id="@+id/cardNumber3" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:layout_marginRight="50dp" 
     android:layout_marginTop="60dp" > 

     <include layout="@layout/card" /> 
    </FrameLayout> 

    <FrameLayout 
     android:id="@+id/cardNumber4" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:layout_below="@+id/cardNumber3" 
     android:layout_marginRight="50dp" 
     android:layout_marginTop="100dp" > 

     <include layout="@layout/card" /> 
    </FrameLayout> 

</RelativeLayout> 


에 대한 XML 코드 여기

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="80dp" 
    android:layout_height="108dp" > 

    <ImageView 
     android:id="@+id/secondImage" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:src="@drawable/back" /> 

    <ImageView 
     android:id="@+id/firstImage" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:src="@drawable/c2" /> 

</FrameLayout> 


됩니다 : 여기


FrameLayouts의 단일 자녀에 대한 XML 코드 한 어린이의 경우 :

public class Card implements OnClickListener { 
    private int _resId; 

    private Context _context; 
    private ImageView firstImage, secondImage; 
    private boolean isFirst; 

    public Card(Context context, FrameLayout parent) { 
     _context = context; 
     firstImage = (ImageView) parent.findViewById(R.id.firstImage); 
     secondImage = (ImageView) parent.findViewById(R.id.secondImage); 

    } 

    public void setupCards(int resId, boolean hasBackSide) { 
     _resId = resId; 
     Bitmap temp = BitmapFactory.decodeResource(_context.getResources(), 
       _resId); 
     firstImage.setImageBitmap(temp); 
     if (hasBackSide) { 
      temp = BitmapFactory.decodeResource(_context.getResources(), 
        R.drawable.back); 
     } 
     secondImage.setImageBitmap(temp); 
     isFirst = true; 
     secondImage.setVisibility(View.GONE); 

    } 

    // MORE IMPLEMENTATION 
} 


이 내 주요 활동 자바 코드 : 나는 잠재적 인 문제의 몇 가지 있다고 생각

public class FaceUpActivity extends Activity { 
    FrameLayout firstCard, secondCard, thirdCard, forthCard; 
    Card cardNumber1, cardNumber2, cardNumber3, cardNumber4; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     initUI(); 
    } 

    private void initUI() { 
     firstCard = (FrameLayout) findViewById(R.id.cardNumber1); 
     secondCard = (FrameLayout) findViewById(R.id.cardNumber2); 
     thirdCard = (FrameLayout) findViewById(R.id.cardNumber3); 
     forthCard = (FrameLayout) findViewById(R.id.cardNumber4); 

     cardNumber1 = new Card(this, firstCard); 
     cardNumber2 = new Card(this, secondCard); 
     cardNumber3 = new Card(this, thirdCard); 
     cardNumber4 = new Card(this, forthCard); 

     cardNumber1.setupCards(R.drawable.c2, true); 
     cardNumber2.setupCards(R.drawable.d0, true); 
     cardNumber3.setupCards(R.drawable.h5, true); 
     cardNumber4.setupCards(R.drawable.sj, true); 

     firstCard.setOnTouchListener(dragMe); 
     secondCard.setOnTouchListener(dragMe); 
     thirdCard.setOnTouchListener(dragMe); 
     forthCard.setOnTouchListener(dragMe); 

    } 

    OnTouchListener dragMe = new OnTouchListener() { 

     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      FrameLayout.LayoutParams params = (LayoutParams) v 
        .getLayoutParams(); 
      int maxWidth = getWindowManager().getDefaultDisplay().getWidth(); 
      int maxHeight = getWindowManager().getDefaultDisplay().getHeight(); 
      int topMargin, leftMargin; 

      int cond = v.getId(); 
      if (cond == R.id.cardNumber1 || cond == R.id.cardNumber2 
        || cond == R.id.cardNumber3 || cond == R.id.cardNumber4) { 
       switch (event.getAction()) { 
       case MotionEvent.ACTION_UP: 

        topMargin = (int) event.getRawY() - (v.getHeight()); 
        leftMargin = (int) event.getRawX() - (v.getWidth())/2; 

        if (topMargin < 0) { 
         params.topMargin = 0; 
        } else if (topMargin > maxHeight) { 
         params.topMargin = maxHeight - v.getHeight(); 
        } else { 
         params.topMargin = topMargin; 
        } 

        if (leftMargin < 0) { 
         params.leftMargin = 0; 
        } else if (leftMargin > maxWidth) { 
         params.leftMargin = maxWidth - (v.getWidth()/2); 
        } else { 
         params.leftMargin = leftMargin; 
        } 

        v.setLayoutParams(params); 

        break; 

       case MotionEvent.ACTION_MOVE: 

        topMargin = (int) event.getRawY() - (v.getHeight()); 
        leftMargin = (int) event.getRawX() - (v.getWidth())/2; 

        if (topMargin < 0) { 
         params.topMargin = 0; 
        } else if (topMargin > maxHeight) { 
         params.topMargin = maxHeight - v.getHeight(); 
        } else { 
         params.topMargin = topMargin; 
        } 

        if (leftMargin < 0) { 
         params.leftMargin = 0; 
        } else if (leftMargin > maxWidth) { 
         params.leftMargin = maxWidth - (v.getWidth()/2); 
        } else { 
         params.leftMargin = leftMargin; 
        } 

        v.setLayoutParams(params); 

        break; 
       } 
      } 
      return true; 
     } 
    }; 
} 

답변

0

당신의 D & D가 작동하지 않는 이유 :

D & D 당신의 카드 (즉 내부 FrameLayout이를 useses) 때문에 작동하지 않습니다는 D & D 이벤트를 "먹는"고 onclick 이벤트를 구현한다.

솔루션은 두 가지 :

당신의 D & D 이벤트의 클릭 이벤트에 대한 하나 (카드의 가장 큰 부분), 하나 (카드의 왼쪽 아래 모서리)이 개 서로 다른 영역을 가질 수있다 . 이 솔루션을 구현 한 Android 뮤직 플레이어에서 실제 예를 볼 수 있습니다.

그렇지 않으면 당신은 같은 시간에 두 개의 이벤트를 처리 할 수 ​​

  • 클릭 == 아래 +까지 같은 시간에 (이 100ms 이하) 같은 X/Y 위치
  • DD에서 == 아래로 + 다른 시간대 (> 50/100ms)
0

: 당신은 당신이 올바른 ID를 받고 있는지

  1. 있습니까 당신의 onTouch()? 나의 나쁜 : 대신 마진의 편집 y 위치를 그래서 X를 사용하고 -
  2. 당신은 FrameLayout를 사용하는 (터치 리스너가 전용 카드 뷰와 함께 사용되기 때문에, 당신은 propably if가 ID를 확인 제거 할 수 있습니다) RelativeLayout을 사용하고 있으므로 여백은 일종의 정확합니다. (당신이 한 때 카드와 아무것도 움직이지 않았다 때 true를 반환하고)하지만, 내가 API는 이벤트, 그렇지 않으면 false을 소비하는 경우 onTouch()true을 반환해야라는 FrameLayout 대신
  3. 을 사용하십시오
+0

안녕하세요, Brian,'onTouch()'는 전혀 호출되지 않았습니다. – thepoosh

관련 문제