2

У меня RelativeLayout есть изображение. Я просто пытаюсь перетащить его во весь макет. Проблема в том, что каждый раз, когда я перетаскиваю его, он возвращается к исходной позиции. Вот мойПеретаскивание для просмотра изображений не работает

drag_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/mainView" 
    android:background="@drawable/bg_animation" 
    tools:context="com.example.activities.AnimationActivity"> 
    <ImageView 
     android:layout_width="100dp" 
     android:layout_height="100dp" 
     android:src="@drawable/ic_launcher" 
     android:id="@+id/appLogo" 
     android:layout_alignBottom="@+id/ba_cell_animation" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="47dp" /> 
</RelativeLayout> 

AnimationActivity.java

public class AnimationActivity extends ActionBarActivity implements View.OnTouchListener, View.OnDragListener { 

    static ImageView mLogo; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_animation); 
     setTitle("Animation"); 
     Typeface mAnimPromptTF = Typeface.createFromAsset(getAssets(), "fonts/Jelloween - Machinato ExtraLight.ttf"); 
     Typeface mAnimBonusTF = Typeface.createFromAsset(getAssets(), "fonts/Jelloween - Machinato SemiBold Italic.ttf"); 
     mAnimPrompt = (TextView) findViewById(R.id.anim_prompt); 
     mAnimBonus = (TextView) findViewById(R.id.anim_bonus); 
     mAnimPrompt.setTypeface(mAnimPromptTF); 
     mAnimBonus.setTypeface(mAnimBonusTF); 

     mLogo = (ImageView) findViewById(R.id.appLogo); 


     mLogo.setOnTouchListener(this); 
     findViewById(R.id.mainView).setOnDragListener(this); 

    } 

    @Override 
    public boolean onTouch(View v, MotionEvent e) { 
     // TODO Auto-generated method stub 
     if (e.getAction() == MotionEvent.ACTION_DOWN) { 
      View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v); 
      v.startDrag(null, shadowBuilder, v, 0); 
      v.setVisibility(View.INVISIBLE); 
      return true; 
     } else { 
      return false; 
     } 
    } 

    @Override 
    public boolean onDrag(View v, DragEvent e) { 
     // TODO Auto-generated method stub 

     switch (e.getAction()) { 
      case DragEvent.ACTION_DROP: 
       View view = (View) e.getLocalState(); 
       ViewGroup from = (ViewGroup) view.getParent(); 
       from.removeView(view); 
       RelativeLayout to = (RelativeLayout) v; 
       to.addView(view); 
       view.setVisibility(View.VISIBLE); 

       break; 

      //the drag point has entered the bounding box of the View 
      case DragEvent.ACTION_DRAG_ENTERED: 
       break; 

      //the user has moved the drag shadow outside the bounding box of the View 
      case DragEvent.ACTION_DRAG_EXITED: 
       break; 

      // the drag and drop operation has concluded. 
      case DragEvent.ACTION_DRAG_ENDED: 
       break; 

      default: 


       break; 
     } 

     return true; 
    } 

    @Override 
    public void onBackPressed() { 
     Intent intent = new Intent(this, MainActivity.class); 
     startActivity(intent); 
    } 
} 

Я пробовал все следующие ссылки, но до сих пор не знаю, где я неправильно:

http://www.vogella.com/tutorials/AndroidDragAndDrop/article.html

http://codingjunkie.net/android-drag-and-drop-part1

http://tech-papers.org/android-drag-and-drop

Я действительно пробовал много.

+0

Это лучше использовать 'MotionEvent' вместо' DragEvent'. Я сделал то же самое [здесь] (http://stackoverflow.com/questions/25844743/draggable-button-getting-out-of-relativelayout-whenever-dragged). –

ответ

0

Попробуйте этот код для перетаскивания, вы можете обратиться к этому link, и он работает, я использовал его.

// Create a string for the ImageView label 
private static final String IMAGEVIEW_TAG = "icon bitmap" 

// Creates a new ImageView 
ImageView imageView = new ImageView(this); 

// Sets the bitmap for the ImageView from an icon bit map (defined elsewhere) 
imageView.setImageBitmap(mIconBitmap); 

// Sets the tag 
imageView.setTag(IMAGEVIEW_TAG); 

    ... 

// Sets a long click listener for the ImageView using an anonymous listener object that 
// implements the OnLongClickListener interface 
imageView.setOnLongClickListener(new View.OnLongClickListener() { 

    // Defines the one method for the interface, which is called when the View is long-clicked 
    public boolean onLongClick(View v) { 

    // Create a new ClipData. 
    // This is done in two steps to provide clarity. The convenience method 
    // ClipData.newPlainText() can create a plain text ClipData in one step. 

    // Create a new ClipData.Item from the ImageView object's tag 
    ClipData.Item item = new ClipData.Item(v.getTag()); 

    // Create a new ClipData using the tag as a label, the plain text MIME type, and 
    // the already-created item. This will create a new ClipDescription object within the 
    // ClipData, and set its MIME type entry to "text/plain" 
    ClipData dragData = new ClipData(v.getTag(),ClipData.MIMETYPE_TEXT_PLAIN,item); 

    // Instantiates the drag shadow builder. 
    View.DragShadowBuilder myShadow = new MyDragShadowBuilder(imageView); 

    // Starts the drag 

      v.startDrag(dragData, // the data to be dragged 
         myShadow, // the drag shadow builder 
         null,  // no need to use local data 
         0   // flags (not currently used, set to 0) 
      ); 

    } 
} 

Пользовательские тень строитель

private static class MyDragShadowBuilder extends View.DragShadowBuilder { 

    // The drag shadow image, defined as a drawable thing 
    private static Drawable shadow; 

     // Defines the constructor for myDragShadowBuilder 
     public MyDragShadowBuilder(View v) { 

      // Stores the View parameter passed to myDragShadowBuilder. 
      super(v); 

      // Creates a draggable image that will fill the Canvas provided by the system. 
      shadow = new ColorDrawable(Color.LTGRAY); 
     } 

     // Defines a callback that sends the drag shadow dimensions and touch point back to the 
     // system. 
     @Override 
     public void onProvideShadowMetrics (Point size, Point touch) 
      // Defines local variables 
      private int width, height; 

      // Sets the width of the shadow to half the width of the original View 
      width = getView().getWidth()/2; 

      // Sets the height of the shadow to half the height of the original View 
      height = getView().getHeight()/2; 

      // The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the 
      // Canvas that the system will provide. As a result, the drag shadow will fill the 
      // Canvas. 
      shadow.setBounds(0, 0, width, height); 

      // Sets the size parameter's width and height values. These get back to the system 
      // through the size parameter. 
      size.set(width, height); 

      // Sets the touch point's position to be in the middle of the drag shadow 
      touch.set(width/2, height/2); 
     } 

     // Defines a callback that draws the drag shadow in a Canvas that the system constructs 
     // from the dimensions passed in onProvideShadowMetrics(). 
     @Override 
     public void onDrawShadow(Canvas canvas) { 

      // Draws the ColorDrawable in the Canvas passed in from the system. 
      shadow.draw(canvas); 
     } 
    } 

Перетащите событие слушателем

// Creates a new drag event listener 
mDragListen = new myDragEventListener(); 

View imageView = new ImageView(this); 

// Sets the drag event listener for the View 
imageView.setOnDragListener(mDragListen); 

... 

protected class myDragEventListener implements View.OnDragListener { 

    // This is the method that the system calls when it dispatches a drag event to the 
    // listener. 
    public boolean onDrag(View v, DragEvent event) { 

     // Defines a variable to store the action type for the incoming event 
     final int action = event.getAction(); 

     // Handles each of the expected events 
     switch(action) { 

      case DragEvent.ACTION_DRAG_STARTED: 

       // Determines if this View can accept the dragged data 
       if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) { 

        // As an example of what your application might do, 
        // applies a blue color tint to the View to indicate that it can accept 
        // data. 
        v.setColorFilter(Color.BLUE); 

        // Invalidate the view to force a redraw in the new tint 
        v.invalidate(); 

        // returns true to indicate that the View can accept the dragged data. 
        return true; 

       } 

       // Returns false. During the current drag and drop operation, this View will 
       // not receive events again until ACTION_DRAG_ENDED is sent. 
       return false; 

      case DragEvent.ACTION_DRAG_ENTERED: 

       // Applies a green tint to the View. Return true; the return value is ignored. 

       v.setColorFilter(Color.GREEN); 

       // Invalidate the view to force a redraw in the new tint 
       v.invalidate(); 

       return true; 

      case DragEvent.ACTION_DRAG_LOCATION: 

       // Ignore the event 
       return true; 

      case DragEvent.ACTION_DRAG_EXITED: 

       // Re-sets the color tint to blue. Returns true; the return value is ignored. 
       v.setColorFilter(Color.BLUE); 

       // Invalidate the view to force a redraw in the new tint 
       v.invalidate(); 

       return true; 

      case DragEvent.ACTION_DROP: 

       // Gets the item containing the dragged data 
       ClipData.Item item = event.getClipData().getItemAt(0); 

       // Gets the text data from the item. 
       dragData = item.getText(); 

       // Displays a message containing the dragged data. 
       Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG); 

       // Turns off any color tints 
       v.clearColorFilter(); 

       // Invalidates the view to force a redraw 
       v.invalidate(); 

       // Returns true. DragEvent.getResult() will return true. 
       return true; 

      case DragEvent.ACTION_DRAG_ENDED: 

       // Turns off any color tinting 
       v.clearColorFilter(); 

       // Invalidates the view to force a redraw 
       v.invalidate(); 

       // Does a getResult(), and displays what happened. 
       if (event.getResult()) { 
        Toast.makeText(this, "The drop was handled.", Toast.LENGTH_LONG); 

       } else { 
        Toast.makeText(this, "The drop didn't work.", Toast.LENGTH_LONG); 

       } 

       // returns true; the value is ignored. 
       return true; 

      // An unknown action type was received. 
      default: 
       Log.e("DragDrop Example","Unknown action type received by OnDragListener."); 
       break; 
     } 

     return false; 
    } 
}; 
+0

Спасибо. Я попробую это. Я хочу знать, где я ошибся. Я просто не могу найти проблему с моим кодом. –

+0

Я не вижу двух разных макетов в вашем xml для перетаскивания. и также я думаю, что вы делаете что-то неправильно, добавляя элементы управления во время выполнения на флаге падения слушателя. – Fahim

+0

Я хочу перетащить в один макет. Как мне это сделать ?. –

0

Изменить DragEvent.ACTION_DROP случай как ниже

case DragEvent.ACTION_DROP: 
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
      LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
    params.setMargins(e.getX(), e.getY(), 0, 0); 
    break; 

Это его вы можете напрямую копировать вставить a bove-код, как есть.

2

Я, наконец, нашел решение, пожалуйста, обратитесь к следующему коду: Проще, чем этот код.

@Override 
    public boolean onTouch(View v, MotionEvent e) { 

     switch (e.getAction()) { 
      case MotionEvent.ACTION_DOWN: 

       View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v); 
       v.startDrag(null, shadowBuilder, v, 0); 
       return true; 
     } 

     return false; 

    } 

    @Override 
    public boolean onDrag(View mainView, DragEvent e) { 
     View view = (View) e.getLocalState(); 
     switch (e.getAction()) { 
      case DragEvent.ACTION_DROP: 
       view.setX(e.getX() - (view.getWidth()/2)); 
       view.setY(e.getY() - (view.getHeight()/2)); 
       view.invalidate(); 
       mainView.invalidate(); 
       return true; 
      case DragEvent.ACTION_DRAG_STARTED: 
       return true; 

      case DragEvent.ACTION_DRAG_EXITED: 
       break; 

      case DragEvent.ACTION_DRAG_ENDED: 
       mainView.invalidate(); 
       return true; 

      default: 


       break; 
     } 

     return true; 
    } 
0

Это кнопка, но подходит для любых видов. Моя кнопка живет в RelativeLayout, и если ваше представление находится в LinearLayout, тогда вам нужно создать LinearLayout.LayoutParams.

код:

addBtn.setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View view, MotionEvent motionEvent) { 
      if (motionEvent.getAction() == MotionEvent.ACTION_MOVE ){ 
       RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(view.getLayoutParams().width, view.getLayoutParams().height); 
       params.setMargins(
         (int) (motionEvent.getRawX() - view.getWidth()/2), // margin left 
         (int) (motionEvent.getRawY() - (view.getHeight()/2)), // margin top 
         (int) (params.width - (motionEvent.getRawX() + view.getWidth()/2)), // margin right 
         (int) (params.height - (motionEvent.getRawY() - (view.getHeight()/2))) // margin bottom 
       ); 
       view.setLayoutParams(params); 
      } 
      return true; 
     } 
    }); 
Смежные вопросы