본문 바로가기
안드로이드 자바

[Java][Android] 이미지 드래그앤 드롭 기능 구현

by teamnova 2021. 12. 1.

이번에는 이미지를 안드로이드 화면에서 드래그 앤 드롭하는 

 

기능을 구현해 보겠습니다.

 

우리가 자주 사용하지만 구현해본 경험은 많지 않을텐데요 

 

시작해볼까요?

 

이미지 개체를 두개의 이미지 뷰 사이로 이동할 수 있는 기능입니다.

 

일단 이미지를 이동할 것인지 여부를 판단해야 합니다. 

 

이것을 판단하는 기준은 오랫동안 클릭하는 것입니다. OnLongClickListener 인터페이스를 구현하기 위해 클래스를 하나 만듭니다.

 

OnLongClickListener 는 화면에서 이미지 개체를 일정 시간 동안 누르게 되면 클릭 이벤트를 받을 수 있습니다.

 

onLongClick 함수의 인수로 넘어온 View 객체에 값을 채우는데 startDrag() 함수를 이용합니다.

 

startDrag() 함수에 필요한 값들을 채우게 되면 드래그 해서 옮길 수 있는 이미지가 됩니다.

 

 

acitivty_main.xml

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/toplinear"
        android:layout_width="fill_parent"
        android:layout_height="170dp"
        android:background="@color/teal_700"
        android:layout_marginBottom="5dp" >

        <ImageView
            android:id="@+id/image"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:src="@drawable/icon" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottomlinear"
        android:layout_width="fill_parent"
        android:layout_height="170dp"
        android:background="@color/teal_700" >

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="이미지를 여기로 드랍하세요 .." />

    </LinearLayout>

</GridLayout>

 

MainAcitvity.java

package com.example.touchevent;

import android.app.Activity;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.View.OnDragListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private ImageView mImg;
    private static final String IMAGEVIEW_TAG = "드래그 이미지";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        mImg = (ImageView) findViewById(R.id.image);
        mImg.setTag(IMAGEVIEW_TAG);

        mImg.setOnLongClickListener(new LongClickListener());

        findViewById(R.id.toplinear).setOnDragListener(
                new DragListener());
        findViewById(R.id.bottomlinear).setOnDragListener(
                new DragListener());

    }

    private final class LongClickListener implements
            OnLongClickListener {

        public boolean onLongClick(View view) {

            // 태그 생성
            ClipData.Item item = new ClipData.Item(
                    (CharSequence) view.getTag());

            String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN };
            ClipData data = new ClipData(view.getTag().toString(),
                    mimeTypes, item);
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
                    view);

            view.startDrag(data, // data to be dragged
                    shadowBuilder, // drag shadow
                    view, // 드래그 드랍할  Vew
                    0 // 필요없은 플래그
            );

            view.setVisibility(View.INVISIBLE);
            return true;
        }
    }

    class DragListener implements OnDragListener {
        Drawable normalShape = getResources().getDrawable(
                R.color.teal_700);
        Drawable targetShape = getResources().getDrawable(
                R.color.purple_200);

        public boolean onDrag(View v, DragEvent event) {

            // 이벤트 시작
            switch (event.getAction()) {

                // 이미지를 드래그 시작될때
                case DragEvent.ACTION_DRAG_STARTED:
                    Log.d("DragClickListener", "ACTION_DRAG_STARTED");
                    break;

                // 드래그한 이미지를 옮길려는 지역으로 들어왔을때
                case DragEvent.ACTION_DRAG_ENTERED:
                    Log.d("DragClickListener", "ACTION_DRAG_ENTERED");
                    // 이미지가 들어왔다는 것을 알려주기 위해 배경이미지 변경
                    v.setBackground(targetShape);
                    break;

                // 드래그한 이미지가 영역을 빠져 나갈때
                case DragEvent.ACTION_DRAG_EXITED:
                    Log.d("DragClickListener", "ACTION_DRAG_EXITED");
                    v.setBackground(normalShape);
                    break;

                // 이미지를 드래그해서 드랍시켰을때
                case DragEvent.ACTION_DROP:
                    Log.d("DragClickListener", "ACTION_DROP");

                    if (v == findViewById(R.id.bottomlinear)) {
                        View view = (View) event.getLocalState();
                        ViewGroup viewgroup = (ViewGroup) view
                                .getParent();
                        viewgroup.removeView(view);

                        // change the text
                        TextView text = (TextView) v
                                .findViewById(R.id.text);
                        text.setText("이미지가 드랍되었습니다.");

                        LinearLayout containView = (LinearLayout) v;
                        containView.addView(view);
                        view.setVisibility(View.VISIBLE);

                    }else if (v == findViewById(R.id.toplinear)) {
                        View view = (View) event.getLocalState();
                        ViewGroup viewgroup = (ViewGroup) view
                                .getParent();
                        viewgroup.removeView(view);

                        LinearLayout containView = (LinearLayout) v;
                        containView.addView(view);
                        view.setVisibility(View.VISIBLE);

                    }else {
                        View view = (View) event.getLocalState();
                        view.setVisibility(View.VISIBLE);
                        Context context = getApplicationContext();
                        Toast.makeText(context,
                                "이미지를 다른 지역에 드랍할수 없습니다.",
                                Toast.LENGTH_LONG).show();
                        break;
                    }
                    break;

                case DragEvent.ACTION_DRAG_ENDED:
                    Log.d("DragClickListener", "ACTION_DRAG_ENDED");
                    v.setBackground(normalShape); // go back to normal shape

                default:
                    break;
            }
            return true;
        }
    }
}

구현한 화면을 한번 볼까요?