0

I have 4 ImageViews in a single RelativeLayout placed such that they are all stacked on top of one another. All of these ImageViews have registered for my drag listener to make them "drop targets". The images they display are all partly transparent such that when they are all placed on top of one another they appear to be one single image.

Elsewhere on the screen there are 4 colored images that "fit" onto each of the 4 in the circle above. Now when I drag the colored images over to the circle and drop them, the only ImageView that ever gets the drop even is the last of the four listed in the XML code. Presumably this one is "on top" and thus is the only one to get drop event notifications.

Somehow, I need to find where the drop occurred and select all the ImageViews which are present at that spot so that I can see if the correct "drop target" was present and update that one accordingly. I have two ideas on how to accomplish this:

  1. I need to get an array of all ImageViews at the X,Y location the drop occurred, then find one with a non-transparent pixel and that is the correct target for the piece I'm dragging.
  2. When the drop occurs, if the current "drop target" ImageView is not the one which matches the piece, I need to check all the other ImageViews in the current RelativeLayout to see if I have the right one there.

Unfortunately, I do not know how to accomplish either of these. My question is essentially, am I missing an easier option when having stacked ImageViews, and if I'm not, then how could I accomplish either of my two ideas above.


This is an example of the image, each of these 4 "sections" of the circle is a separate image with a transparent background:


The truncated XML code I used to place them together is:

<RelativeLayout 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
       >
   <ImageView
    android:id="@+id/circlepuz1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="false"
    android:src="@drawable/circle_part1"
    android:layout_gravity="center_horizontal"
    android:tag="bottom_right" />

   <ImageView
    android:id="@+id/circlepuz2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@id/circlepuz1"
    android:layout_alignRight="@id/circlepuz1"
    android:layout_alignTop="@id/circlepuz1"
    android:layout_alignBottom="@id/circlepuz1"
    android:scaleType="fitXY"
    android:src="@drawable/circle_part2"
    android:tag="bottom_left" />

...
Every other ImageView is the same id+1, allignXXX=@id/circlepuz1

The current Java drop code is:

case DragEvent.ACTION_DROP:        
    //handle the dragged view being dropped over a target view
    View view = (View) draggedView.getLocalState(); 
    //stop displaying the view where it was before it was dragged
    view.setVisibility(View.INVISIBLE); 

    //view dragged item is being dropped on
    ImageView dropTarget = (ImageView) dropTargetView; 

    //view being dragged and dropped
    ImageView dropped = (ImageView) view;

    // I name the "drag" ImageView's tag and the "drop" ImageView's tag the same thing
    // so if they match, I know the piece is in the right place
    Object tag = dropped.getTag();
    Object dtag = dropTarget.getTag();

    if(tag.toString() != dtag.toString()){   // piece was in the wrong place
      Log.d(TAG, tag.toString() + " was not " + dtag.toString());
      view.setVisibility(View.VISIBLE); 
    }
    else {   // piece is in the right place
      dropTarget.setImageDrawable(dropped.getDrawable());
    }

I want to loop that last if/else check for each ImageView in the same Layout to see if the correct one is present, I tried something like:

    // Attempt to get the new ImageView 
    //ImageView test = (ImageView) findViewById(dropTarget.getNextFocusDownId());

Which didn't work at all. The other thought was to get the X & Y of the "drop" which is easy to do:

    String toastText = "X: " + draggedView.getX() + "\nY:" + draggedView.getY();
    Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_LONG).show();

But I'm not sure from here how to check what other ImageViews have that point within them.

Mike
  • 47,263
  • 29
  • 113
  • 177
  • can see my quastion? http://stackoverflow.com/questions/29051192/how-defined-target-for-drag-and-drop-image?noredirect=1#comment46340268_29051192 – zahra Mar 15 '15 at 07:11

1 Answers1

0

I ended up going with the second option:

"2.When the drop occurs, if the current "drop target" ImageView is not the one which matches the piece, I need to check all the other ImageViews in the current RelativeLayout to see if I have the right one there."

The answer ended up being easier than I thought it was going to be, in order to get all the other ImageViews at the same place, I just need to check with the parent to get a list of present ImageViews (available in a ViewGroup) then iterate through the tags I set looking for a match:

case DragEvent.ACTION_DROP:        
    //handle the dragged view being dropped over a target view
    View view = (View) draggedView.getLocalState(); 

    //stop displaying the view where it was before it was dragged
    view.setVisibility(View.INVISIBLE); 

    //view dragged item is being dropped on
    ImageView dropTarget = (ImageView) dropTargetView; 
    //view being dragged and dropped
    ImageView dropped = (ImageView) view;

    // In this case the "dropTarget" is the "top most" ImageView of my stacked circles
    // I can create a ViewGroup of the parent of this ImageView (which is the 
    // RelativeLayout) in order to check all the children (other ImageViews)
    ViewGroup vg = (ViewGroup) dropTarget.getParent();

    Object tag = dropped.getTag();

    // Now I can iterate through each of the children (ImageViews) in the ViewGroup
    // looking to see if the dragged puzzle piece is a match for one of the "drop"
    // ImageViews
    for(int i = 0; i<vg.getChildCount(); i++){
        ImageView temp = (ImageView) vg.getChildAt(i);
        Object dtag = temp.getTag();
            if(dtag.toString().equals(tag.toString())){
                // Then we have a match! Place the piece
Mike
  • 47,263
  • 29
  • 113
  • 177