Как реализовать Drag and Drop в Android 2.2? - PullRequest
2 голосов
/ 16 февраля 2012

Я пытаюсь разработать приложение для Android, где пользователь должен иметь возможность перетаскивать изображения из одной ячейки сетки в другую.Для реализации этого мне нужен Drag and Drop API, который был представлен в Android 3.0, но мое приложение должно работать в Android 2.2.Итак, есть ли способ реализовать это с помощью событий Touch?Если да, то, пожалуйста, предоставьте мне фрагмент кода или ссылку, в которой он кратко описан.

Ответы [ 4 ]

15 голосов
/ 11 июля 2012

Привет после долгого времени получить успех сделать перетаскивание в Android 2.2

здесь я даю свой код, который даст вам успех. Мой основной класс здесь

 package info.tempDD;

    import android.app.Activity;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.os.Bundle;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.ViewGroup;
    import android.view.ViewGroup.LayoutParams;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.ImageView;
    import android.widget.RelativeLayout;

   public class TempDDActivity extends Activity implements OnTouchListener {
        /** Called when the activity is first created. */
        private View selected_item = null;
        private int offset_x = 0;
        private int offset_y = 0;
        Boolean touchFlag=false;
        boolean dropFlag=false;
        LayoutParams imageParams;
        ImageView imageDrop,image1,image2;
        int crashX,crashY;
        Drawable dropDrawable,selectDrawable;
        Rect dropRect,selectRect;
        int topy,leftX,rightX,bottomY;

        int dropArray[];    

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            setContentView(R.layout.main);
            ViewGroup container = (ViewGroup) findViewById(R.id.container);
            imageDrop=(ImageView) findViewById(R.id.ImgDrop);       
            image1=(ImageView) findViewById(R.id.img);      
            image2=(ImageView) findViewById(R.id.img2);
            container.setOnTouchListener(new View.OnTouchListener() 
            {
                public boolean onTouch(View v, MotionEvent event) 
                {
                    if(touchFlag==true)
                    {
                        System.err.println("Display If  Part ::->"+touchFlag);
                        switch (event.getActionMasked()) 
                        {
                        case MotionEvent.ACTION_DOWN :

                             topy=imageDrop.getTop();
                             leftX=imageDrop.getLeft();
                             rightX=imageDrop.getRight();   
                             bottomY=imageDrop.getBottom();
                            System.err.println("Display Top-->"+topy);      
                            System.err.println("Display Left-->"+leftX);
                            System.err.println("Display Right-->"+rightX);
                            System.err.println("Display Bottom-->"+bottomY);                


                            //opRect.
                            break;
                        case MotionEvent.ACTION_MOVE:
                            crashX=(int) event.getX();
                            crashY=(int) event.getY();
                            System.err.println("Display Here X Value-->"+crashX);
                            System.err.println("Display Here Y Value-->"+crashY);

                            int x = (int) event.getX() - offset_x;
                            int y = (int) event.getY() - offset_y;                                          
                            //int w = getWindowManager().getDefaultDisplay().getWidth() - 100;
                            //int h = getWindowManager().getDefaultDisplay().getHeight() - 100;
                            int w = getWindowManager().getDefaultDisplay().getWidth() - 50;
                            int h = getWindowManager().getDefaultDisplay().getHeight() - 10;
                            if (x > w)
                                x = w;
                            if (y > h)
                                y = h;                      
                            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(new ViewGroup.MarginLayoutParams(  RelativeLayout.LayoutParams.WRAP_CONTENT,   RelativeLayout.LayoutParams.WRAP_CONTENT));
                            lp.setMargins(x, y, 0, 0);                  

                            //Drop Image Here                       
                            if(crashX > leftX && crashX < rightX && crashY > topy && crashY < bottomY )                     
                            {                           
                                Drawable temp=selected_item.getBackground();                            
                                imageDrop.setBackgroundDrawable(temp);
                                imageDrop.bringToFront();                           
                                dropFlag=true;
                                selected_item.setVisibility(View.INVISIBLE);
                            }
                            //Drop Image Here                       
                            selected_item.setLayoutParams(lp);
                            break;  
                        case MotionEvent.ACTION_UP:
                            //                      
                            touchFlag=false;
                            if(dropFlag==true)
                            {
                                dropFlag=false;
                            }
                            else
                            {
                                selected_item.setLayoutParams(imageParams);
                            }                       
                            break;
                        default:
                            break;
                        }
                    }else
                    {
                        System.err.println("Display Else Part ::->"+touchFlag);
                    }               
                    return true;
                }
            });

            image1.setOnTouchListener(this);
            image2.setOnTouchListener(this);
        }

        public boolean onTouch(View v, MotionEvent event) 
        {   
            switch (event.getActionMasked()) 
            {
            case MotionEvent.ACTION_DOWN:
                touchFlag=true;
                offset_x = (int) event.getX();
                offset_y = (int) event.getY();
                selected_item = v;
                imageParams=v.getLayoutParams();
                break;
            case MotionEvent.ACTION_UP:
                selected_item=null;
                touchFlag=false;
                break;
            default:
                break;
            }       
            return false;
        }
    }

После этого создайте один класс и расширьте ваш основной макет, как RelativeLayout

package info.tempDD;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;

public class TouchInterceptor extends RelativeLayout {
    public TouchInterceptor(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        return super.onInterceptTouchEvent(ev);
    }

}

и файл Main My Xml

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

    <ImageView
        android:id="@+id/ImgDrop"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentTop="true"
        android:layout_centerInParent="true"
        android:layout_marginTop="50dp"
        android:background="#FFFFFF" >
    </ImageView>

    <ImageView
        android:id="@+id/img"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/ic_launcher" >
    </ImageView>

    <ImageView
        android:id="@+id/img2"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:background="@drawable/ic_launcher" >
    </ImageView>

</RelativeLayout>

Хорошо, теперь я счастлив, что выполнил свою работу, а также счастлив, потому что я доволен своей работой. Надеюсь, это поможет вам. и ссылка, которая дает мне путь ниже.

2 голосов
/ 13 мая 2015

view.setOnTouchListener (новый View.OnTouchListener () {

        public boolean onTouch(View v, MotionEvent me) {


            if (me.getAction() == MotionEvent.ACTION_MOVE) {


                v.setX(me.getRawX() - (v.getWidth() / 2));
                v.setY(me.getRawY() - (float)(v.getHeight()* 1.5 / 2));

            }

            return true;
        }
    }

);

2 голосов
/ 24 января 2013

DragDropManager.class

package com.example.dragdrop;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import android.annotation.TargetApi;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.view.ActionMode;
import android.view.ActionMode.Callback;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.PopupWindow;

public class DragDropManager
{
    private static DragDropManager instance;
    private Activity mActivity;
    private List<View> dropzones;
    private Map<View, Integer> dropzonestates;
    private Map<View, DropZoneListener> dropzonelisteners;
    private PopupWindow popoup;
    private MotionEvent firstEvent;
    private Rect rect;
    private Object item;

    public static DragDropManager getInstance()
    {
        if (instance == null) instance = new DragDropManager();
        return instance;
    }

    private DragDropManager()
    {
    }

    public void init(Activity a)
    {
        mActivity = a;
        dropzones = new ArrayList<View>();
        dropzonelisteners = new HashMap<View, DropZoneListener>();
        dropzonestates = new HashMap<View, Integer>();
        rect = new Rect();
    }

    public void addDropZone(View zone, DropZoneListener zonelistener)
    {
        dropzones.add(zone);
        dropzonelisteners.put(zone, zonelistener);
        dropzonestates.put(zone, 0);
    }

    public void clearZones()
    {
        dropzones.clear();
        dropzonelisteners.clear();
        dropzonestates.clear();
    }

    public void clearZone(View zone)
    {
        dropzones.remove(zone);
        dropzonelisteners.remove(zone);
        dropzonestates.remove(zone);
    }

    private void checkDropZones(MotionEvent event)
    {
        boolean isOver;
        HashSet<DropZoneListener> listeners = new HashSet<DropZoneListener>(dropzonelisteners.values());

        for (View zone : dropzones)
        {
            int[] location = new int[2];
            zone.getLocationInWindow(location);
            zone.getDrawingRect(rect);
            rect.offset(location[0], location[1]);
            isOver = rect.contains((int) event.getRawX(), (int) event.getRawY());

            switch (dropzonestates.get(zone))
            {
                case 0:
                    if (isOver)
                    {
                        for(DropZoneListener listener:listeners)
                        {
                            listener.OnDragZoneEntered(zone, item); 
                        }
                        dropzonestates.put(zone, 1);
                    }

                    break;
                case 1:
                    if (!isOver)
                    {
                        for(DropZoneListener listener:listeners)
                        {
                            listener.OnDragZoneLeft(zone, item);    
                        }
                        dropzonestates.put(zone, 0);
                    }
                    else if (isOver && event.getAction()==MotionEvent.ACTION_UP)
                    {
                        for(DropZoneListener listener:listeners)
                        {
                            listener.OnDropped(zone, item); 
                        }
                        dropzonestates.put(zone, 0);
                    }
                    break;
            }
        }
    }

    public void startDragging(final View dragView, Object item)
    {
        this.item = item;
        // Copy view Bitmap (Clone Object visual)
        ImageView view = new ImageView(mActivity);
        view.measure(dragView.getWidth(), dragView.getHeight());

        Bitmap returnedBitmap = Bitmap.createBitmap(dragView.getWidth(), dragView.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);
        dragView.draw(canvas);

        view.setBackgroundDrawable(new BitmapDrawable(dragView.getResources(), returnedBitmap));

        // Set up Window
        popoup = new PopupWindow(view, dragView.getWidth(), dragView.getHeight());
        popoup.setWindowLayoutMode(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        // set window at position
        int[] location = new int[2];
        dragView.getLocationInWindow(location);
        popoup.showAtLocation(mActivity.getWindow().getDecorView(), Gravity.NO_GRAVITY, location[0], location[1]);
        // Switch call Backs
        callbackDefault = mActivity.getWindow().getCallback();
        mActivity.getWindow().setCallback(callback);
    }

    private android.view.Window.Callback callbackDefault;

    private android.view.Window.Callback callback = new android.view.Window.Callback()
    {

        @Override
        public boolean dispatchGenericMotionEvent(MotionEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchKeyEvent(KeyEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchKeyShortcutEvent(KeyEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean dispatchTouchEvent(MotionEvent event)
        {
            checkDropZones(event);

            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
                // popoup.update((int)event.getRawX(), (int)event.getRawY(), -1,
                // -1);
            }

            if (event.getAction() == MotionEvent.ACTION_MOVE)
            {
                if (firstEvent == null) firstEvent = MotionEvent.obtain(event);

                // Log.v("EVENT","X:"+event.getRawX() + " _X:" + location[0] +
                // " __X:" + firstEvent.getRawX());
                // Log.v("EVENT","Y:"+event.getRawY() + " _Y:" + location[1] +
                // " __Y:" + firstEvent.getRawY());

                float pos_x = event.getRawX() + (-popoup.getWidth() / 2);
                float pos_y = event.getRawY() + (-popoup.getHeight() / 2);

                popoup.update((int) pos_x, (int) pos_y, -1, -1);

            }

            if (event.getAction() == MotionEvent.ACTION_UP)
            {
                popoup.dismiss();
                mActivity.getWindow().setCallback(callbackDefault);
            }

            return false;
        }

        @Override
        public boolean dispatchTrackballEvent(MotionEvent event)
        {
            return false;
        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public void onActionModeFinished(ActionMode mode)
        {
            // TODO Auto-generated method stub

        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public void onActionModeStarted(ActionMode mode)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAttachedToWindow()
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onContentChanged()
        {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean onCreatePanelMenu(int featureId, Menu menu)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public View onCreatePanelView(int featureId)
        {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        public void onDetachedFromWindow()
        {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean onMenuItemSelected(int featureId, MenuItem item)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onMenuOpened(int featureId, Menu menu)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void onPanelClosed(int featureId, Menu menu)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu)
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onSearchRequested()
        {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams attrs)
        {
            // TODO Auto-generated method stub

        }

        @Override
        public void onWindowFocusChanged(boolean hasFocus)
        {
            // TODO Auto-generated method stub

        }

        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        @Override
        public ActionMode onWindowStartingActionMode(Callback callback)
        {
            // TODO Auto-generated method stub
            return null;
        }

    };

    public interface DropZoneListener
    {

        void OnDragZoneEntered(View zone, Object item);

        void OnDragZoneLeft(View zone, Object item);

        void OnDropped(View zone, Object item);

    }
}

MainActivity.class

package com.example.dragdrop;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.example.dragdrop.DragDropManager.DropZoneListener;

public class MainActivity extends Activity implements OnLongClickListener, OnTouchListener
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DragDropManager.getInstance().init(this);

        Button b1 = (Button) findViewById(R.id.button1);
        Button b2 = (Button) findViewById(R.id.button2);
        Button b3 = (Button) findViewById(R.id.button3);

        EditText et1 = (EditText) findViewById(R.id.editText1);
        TextView tv1 = (TextView) findViewById(R.id.textView1);

        Button b4 = (Button) findViewById(R.id.button4);
        Button b5 = (Button) findViewById(R.id.button5);
        Button b6 = (Button) findViewById(R.id.button6);

        b1.setOnTouchListener(this);
        b2.setOnLongClickListener(this);
        b3.setOnTouchListener(this);

        et1.setOnTouchListener(this);
        tv1.setOnTouchListener(this);

        DragDropManager.getInstance().addDropZone(b4, dropZoneListener1);
        DragDropManager.getInstance().addDropZone(b5, dropZoneListener1);
        DragDropManager.getInstance().addDropZone(b6, dropZoneListener1);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    DropZoneListener dropZoneListener1 = new DropZoneListener()
    {

        @Override
        public void OnDropped(View zone, Object item)
        {
            Log.v("ddddd","drop time");
            switch(zone.getId())
            {
                case R.id.button4:
                    if (item instanceof String) 
                        ((Button)zone).setText("DROP ITEM OK");
                    else    
                        ((Button)zone).setText("DROP ITEM ERR");

                    break;
                case R.id.button5:
                    ((Button)zone).setText("DROP");
                    break;
                case R.id.button6:
                    if (item instanceof Integer) 
                        ((Button)zone).setText("DROP ITEM OK");
                    else    
                        ((Button)zone).setText("DROP ITEM ERR");
                    break;
            }

        }

        @Override
        public void OnDragZoneLeft(View zone, Object item)
        {

            switch(zone.getId())
            {
                case R.id.button4:
                    ((Button)zone).setText("LEFT");
                    break;
                case R.id.button5:
                    ((Button)zone).setText("LEFT");
                    break;
                case R.id.button6:
                    ((Button)zone).setText("LEFT");
                    break;
            }
        }

        @Override
        public void OnDragZoneEntered(View zone, Object item)
        {
            switch(zone.getId())
            {
                case R.id.button4:
                    if (item instanceof String) 
                        ((Button)zone).setText("ENTER ITEM OK");
                    else    
                        ((Button)zone).setText("ENTER ITEM ERR");
                    break;
                case R.id.button5:
                    ((Button)zone).setText("ENTER");
                    break;
                case R.id.button6:
                    if (item instanceof Integer) 
                        ((Button)zone).setText("ENTER ITEM OK");
                    else    
                        ((Button)zone).setText("ENTER ITEM ERR");
                    break;
            }
        }
    };

    @Override
    public boolean onLongClick(View v)
    {
        DragDropManager.getInstance().startDragging(v, 0);
        return false;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event)
    {
        DragDropManager.getInstance().startDragging(v, "String");
        return false;
    }

}

activity_main.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"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="14dp"
        android:text="Click" />

    <Button
        android:id="@+id/button2"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="29dp"
        android:text="Long" />

    <Button
        android:id="@+id/button3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/button2"
        android:layout_below="@+id/button2"
        android:layout_marginTop="16dp"
        android:text="Click" />

    <Button
        android:id="@+id/button6"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignTop="@+id/button3"
        android:layout_marginLeft="39dp"
        android:layout_toRightOf="@+id/button3"
        android:text="Drop3" />

    <Button
        android:id="@+id/button5"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignLeft="@+id/button4"
        android:layout_centerVertical="true"
        android:text="Drop2" />

    <Button
        android:id="@+id/button4"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_above="@+id/button5"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="35dp"
        android:layout_marginRight="20dp"
        android:text="Drop1" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button3"
        android:layout_below="@+id/button3"
        android:layout_marginTop="17dp"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/button6"
        android:layout_alignParentLeft="true"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

У меня есть вдохновение от MobileAnarchyWidget, но я кое-что улучшаю.

Как вы можете видеть, я использую PopupWindow для создания dragEfect, даже когда я клонирую визуальную часть из перетаскиваемого объекта. Также мне не нужно использовать какую-либо часть макета. Просто поместите DragDropManager.class в ваш проект. Никаких изменений не требуется. Никаких дополнительных ресурсов. Больше зон может быть поражено одновременно, если одна зона полностью / частично покрывает другую. Вы можете перетащить все, что хотя бы на вид. Я переключаю функцию обратного вызова в окне «Активность», чтобы при перетаскивании чего-либо еще не было доступа к событиям. В этом решении вы никогда не теряете фокус из Draggable, а также когда вы поднимаете палец вверх на экране, DragDrop автоматически завершается (активность восстанавливает контроль над обратными вызовами).

У меня нет времени, чтобы показать вам все комбинации для использования. Но, как вы можете видеть, есть только один DropZoneListener. Вы можете использовать больше, но помните, что все слушатели вызываются, и все измененные состояния перетаскивания отправляются каждому слушателю.

пример: Дропзоны D1, D2; Слушатель L1, L2;

если D1 или D2 изменились L1 (Dx) и L2 (Dx)

если D1 и D2 изменились L1 (D1, D2) и L2 (D1, D2)

Но это хорошо, потому что вы знаете, если оно упало где-то еще. И я забываю, что DragItem - это Object, поэтому при удалении вы должны разрешить тип объекта. Но это также хорошо, потому что при использовании фрагментов вы никогда не знаете, какие данные можно перетаскивать.

В моем решении я проверяю на уровне типа объекта. Если объект не поддерживается dragzone, вы узнаете.

0 голосов
/ 16 февраля 2012

TouchEvent: TouchDown -> LockItemOnTouchPoint

FollowTouchDirections -> UpdateItemPosition

TouchEvent: TouchUp -> LockItemPosition

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...