首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无法在android studio中拖放简单的imageView

无法在android studio中拖放简单的imageView
EN

Stack Overflow用户
提问于 2016-12-16 19:16:16
回答 3查看 1.9K关注 0票数 18

我正在尝试在android studio中创建一个简单的拖放图像。我可以让图像在屏幕上拖动,我一松开它,它就消失了。在控制台中,我得到一个"Reporting drop result: false“

下面是我的代码:

代码语言:javascript
复制
ImageView mImageView;
String mString;

private android.widget.RelativeLayout.LayoutParams mLayoutParams;

    mImageView.setOnLongClickListener(new View.OnLongClickListener(){
        @Override
        public boolean onLongClick(View v){
            ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
            String[] mimeTypes = {
                    ClipDescription.MIMETYPE_TEXT_PLAIN
            };
            ClipData dragData = new ClipData(v.getTag().toString(), mimeTypes, item);
            View.DragShadowBuilder myShadow = new View.DragShadowBuilder(mImageView);

            v.startDrag(dragData, myShadow, null, 0);
            return true;
        }
    });

    mImageView.setOnDragListener(new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch(event.getAction()) {
                case DragEvent.ACTION_DRAG_STARTED:
                    mLayoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
                    Log.d(mString, "Action is DragEvent.ACTION_DRAG_STARTED");

                    // Do nothing
                    break;

                case DragEvent.ACTION_DRAG_ENTERED:
                    Log.d(mString, "Action is DragEvent.ACTION_DRAG_ENTERED");
                    int x_cord = (int) event.getX();
                    int y_cord = (int) event.getY();
                    break;

                case DragEvent.ACTION_DRAG_EXITED :
                    Log.d(mString, "Action is DragEvent.ACTION_DRAG_EXITED");
                    x_cord = (int) event.getX();
                    y_cord = (int) event.getY();
                    mLayoutParams.leftMargin = x_cord;
                    mLayoutParams.topMargin = y_cord;
                    v.setLayoutParams(mLayoutParams);
                    break;

                case DragEvent.ACTION_DRAG_LOCATION  :
                    Log.d(mString, "Action is DragEvent.ACTION_DRAG_LOCATION");
                    x_cord = (int) event.getX();
                    y_cord = (int) event.getY();
                    break;

                case DragEvent.ACTION_DRAG_ENDED   :
                    Log.d(mString, "Action is DragEvent.ACTION_DRAG_ENDED");

                    // Do nothing
                    break;

                case DragEvent.ACTION_DROP:
                    Log.d(mString, "ACTION_DROP event");

                    // Do nothing
                    break;
                default: break;
            }
            return true;
        }
    });

    mImageView.setOnTouchListener(new View.OnTouchListener(){
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                ClipData data = ClipData.newPlainText("", "");
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(mImageView);

                mImageView.startDrag(data, shadowBuilder, mImageView, 0);
                mImageView.setVisibility(View.INVISIBLE);
                return true;
            } else {
                return false;
            }
        }
    });
}

}

EN

回答 3

Stack Overflow用户

发布于 2017-03-12 04:06:38

已编辑:更改为如何使用onTouch移动RelativeLayout中包含的所有视图的工作示例。我认为onDrag事件更适用于拖放数据项,而不是移动视图。

代码语言:javascript
复制
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
    private RelativeLayout mRelLay;
    private float mInitialX, mInitialY;
    private int mInitialLeft, mInitialTop;
    private View mMovingView = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRelLay = (RelativeLayout) findViewById(R.id.relativeLayout);

        for (int i = 0; i < mRelLay.getChildCount(); i++)
            mRelLay.getChildAt(i).setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        RelativeLayout.LayoutParams mLayoutParams;

        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mMovingView = view;
                mLayoutParams = (RelativeLayout.LayoutParams) mMovingView.getLayoutParams();
                mInitialX = motionEvent.getRawX();
                mInitialY = motionEvent.getRawY();
                mInitialLeft = mLayoutParams.leftMargin;
                mInitialTop = mLayoutParams.topMargin;
                break;

            case MotionEvent.ACTION_MOVE:
                if (mMovingView != null) {
                    mLayoutParams = (RelativeLayout.LayoutParams) mMovingView.getLayoutParams();
                    mLayoutParams.leftMargin = (int) (mInitialLeft + motionEvent.getRawX() - mInitialX);
                    mLayoutParams.topMargin = (int) (mInitialTop + motionEvent.getRawY() - mInitialY);
                    mMovingView.setLayoutParams(mLayoutParams);
                }
                break;

            case MotionEvent.ACTION_UP:
                mMovingView = null;
                break;
        }

        return true;
    }
}
票数 8
EN

Stack Overflow用户

发布于 2017-03-11 22:56:56

给定的代码中有一个问题很容易修复。应该为目标(或任何可能的目标)视图设置OnDragListener()。因此在源代码视图上设置了OnLongClickListener()OnTouchListener(),然后应该有OnDragListener()imageView2。这是一个很长的解释,但应该是一个简单的修复。

请参阅drag-drop以获取一个很好的示例。

如果处理得当,解决方案的其余部分会涉及更多(但是,有一个变通的方法)。

开始拖动时,基本上您需要将图像复制到剪贴板,然后将其粘贴到drop视图中。这需要先创建一个ContentProvider,然后再使用ContentResolver (link)。

剪贴板文档:ClipData

我有未来的计划,为一个应用程序这样做,但这不会很快发生,所以,不幸的是,我不能提供任何代码。

然而,有一种变通方法,涉及的内容要少得多。

在可能要移动的任何图像上设置标记。

代码语言:javascript
复制
imageView.setTag("ImageTag1");

onLongClick()中,按照问题中的操作设置itemdragData

然后在OnDragListener()中,读取标签,确定哪个图像正在被丢弃,然后将该图像设置为视图。如下所示:

代码语言:javascript
复制
case DragEvent.ACTION_DROP:
    ClipData.Item item = event.getClipData().getItemAt(0);
    CharSequence dragData = item.getText();

    if(dragData.equals("ImageTag1")) {
        // this gets jpg image from "drawable" folder,
        //      set ImageView appropriately for your usage
        ((ImageView)v).setImageResource(R.drawable.image1);                            
    } else if(dragData.equals("ImageTag2")) {
        ((ImageView)v).setImageResource(R.drawable.image2);
    }
    break;

在大小写为"ACTION_DRAG_EXITED“的情况下,您也需要执行类似的操作。如果将图像放在无效区域,则会将图像放回原始视图。

票数 5
EN

Stack Overflow用户

发布于 2017-03-15 10:45:17

这就是我在我的应用中如何做到这一点:

对于您想要拖动的“视图”,在onTouchListener中进行设置:

代码语言:javascript
复制
    public final class ChoiceTouchListener implements OnTouchListener {
    Context context;
    //int index;
    public static float offsetX = 0,offsetY = 0;

    DragShadowBuilder shadowBuilder;

    public ChoiceTouchListener(Context context) {
        super();
        this.context = context;
        //this.index = index;
    }




    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {

            //view.setTag("option"+index);
            ClipData data = ClipData.newPlainText("tag", view.getTag().toString());
            shadowBuilder = new View.DragShadowBuilder(view);

            //start dragging the item touched
            view.startDrag(data, shadowBuilder, view, 0);

            offsetX = view.getLeft();//(int)view.getX();//(int)motionEvent.getX();
            offsetY = view.getTop();//(int)view.getY();//motionEvent.getY();
            view.setVisibility(View.INVISIBLE);
            Log.v("here","it is ::" + (int)motionEvent.getX() + " , "+(int)motionEvent.getY());

            return false;



        }

        return true;

    }
}

这是一个在中间设置了目标“RelativeLayout”的视图,用于侦听拖放事件:

代码语言:javascript
复制
    public class DragLayout extends RelativeLayout {

    boolean DEBUG = true;

    AnimationDrawable blenderAnim;
    Handler handlerAnim2;
    Context context;

    private int dimensionInPixel = 200;
    int screenWidth,screenHeight;

    public DragLayout(Context context) {
        super(context);

        this.context = context;

        //not to include in main program
        getDimensionsofScreen();

        setLayout();
        setViews();

    }



    private void setLayout() {


        // set according to parent layout (not according to current layout)
        RelativeLayout.LayoutParams rLp = new RelativeLayout.LayoutParams(
                LayoutParams.MATCH_PARENT,  LayoutParams.MATCH_PARENT);
        rLp.topMargin = 2 * (screenHeight / 25); // calculating 1/10 of 4/5
        // screen


        this.setLayoutParams(rLp);

    }

    void setViews() {

        ImageView img2 = new ImageView(context);

        int dimensionInDp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dimensionInPixel, getResources().getDisplayMetrics());

        RelativeLayout.LayoutParams rLp = new RelativeLayout.LayoutParams(
                (screenWidth / 5), (screenHeight / 5));
        rLp.topMargin = (screenHeight / 10);
        rLp.leftMargin = (4*screenWidth / 10);
        rLp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);

        img2.setLayoutParams(rLp);
        img2.getLayoutParams().height = dimensionInDp;
        img2.getLayoutParams().width = dimensionInDp;
        img2.setImageDrawable(getResources().getDrawable(R.drawable.blender_anim));
        img2.setOnDragListener(new ChoiceDragListener(context));
        this.addView(img2);

        blenderAnim = (AnimationDrawable)img2.getDrawable();
        blenderAnim.setOneShot(true);
        blenderAnim.stop();

    }


    public ArrayList<Integer> getDimensionsofScreen() {

        //metrics that holds the value of height and width
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();;
        ArrayList<Integer> vals = new ArrayList<Integer>();

        vals.add(displayMetrics.widthPixels);
        vals.add(displayMetrics.heightPixels);
        screenHeight = displayMetrics.heightPixels;
        screenWidth = displayMetrics.widthPixels;

        return vals;
    }



    @SuppressLint("NewApi")
    @Override
    public boolean onDragEvent(DragEvent event) {

        int mCurX = (int) event.getX();
        int mCurY = (int) event.getY();

        if(event.getAction() == DragEvent.ACTION_DRAG_STARTED || event.getAction() == DragEvent.ACTION_DRAG_ENTERED) {
            if (blenderAnim.isRunning()) {
                blenderAnim.stop();
            } else {
                blenderAnim.run();

                handlerAnim2 = new Handler();
                handlerAnim2.postDelayed(
                        new Runnable(){

                            @Override
                            public void run() {
                                blenderAnim.stop();

                            }},
                        getAnimationDuration(blenderAnim));
            }
        }

        if(event.getAction() == DragEvent.ACTION_DROP || event.getAction() == DragEvent.ACTION_DRAG_EXITED) {

            if (blenderAnim.isRunning()) {
                blenderAnim.stop();
            } else {
                blenderAnim.run();

                handlerAnim2 = new Handler();
                handlerAnim2.postDelayed(
                        new Runnable(){

                            @Override
                            public void run() {
                                blenderAnim.stop();

                            }},
                        getAnimationDuration(blenderAnim));
            }

            Log.v("here", "it is :: " + mCurX + ", " + mCurY);

            View view1 = (View) event.getLocalState();
            view1.setVisibility(View.VISIBLE);
            ObjectAnimator animationx = ObjectAnimator.ofFloat(view1,"translationX", mCurX - ChoiceTouchListener.offsetX-(screenWidth / 10),0.0f);
            ObjectAnimator animationy = ObjectAnimator.ofFloat(view1, "translationY", mCurY - ChoiceTouchListener.offsetY - (screenHeight / 10), 0.0f);
            AnimatorSet animSet = new AnimatorSet();
            animSet.setDuration(500);
            animSet.playTogether(animationx,animationy);

            animSet.start();

        }
        if(event.getAction() == DragEvent.ACTION_DROP || event.getAction() == DragEvent.ACTION_DRAG_ENDED){
            if(blenderAnim.isRunning()){
                blenderAnim.stop();
            }
        }
        return true;


    }

    private int getAnimationDuration(AnimationDrawable src){
        int dur = 0;
        for(int i=0; i<src.getNumberOfFrames(); i++){
            dur += src.getDuration(i);
        }
        return dur;
    }
}

这是DragLayout中ImageView的拖动监听程序:

代码语言:javascript
复制
    public class ChoiceDragListener implements View.OnDragListener {

    boolean DEBUG = true;
    Context context;
    public String TAG = "Drag Layout:";

    public ChoiceDragListener(Context context){
        this.context = context;
    }

    @Override
    public boolean onDrag(View v, DragEvent event) {
        switch (event.getAction()) {
            case DragEvent.ACTION_DRAG_STARTED:
                if(DEBUG) Log.v("here","drag started");
                break;
            case DragEvent.ACTION_DRAG_ENTERED:
                break;
            case DragEvent.ACTION_DRAG_LOCATION:
                int mCurX = (int) event.getX();
                int mCurY = (int) event.getY();

                if(DEBUG) Log.v("Cur(X, Y) : " ,"here ::" + mCurX + ", " + mCurY );

                break;
            case DragEvent.ACTION_DRAG_EXITED:

                if(DEBUG)
                    Log.v("here","drag exits");

                break;
            case DragEvent.ACTION_DROP:

                //handle the dragged view being dropped over a drop view
                View view = (View) event.getLocalState();
                ClipData cd =  event.getClipData();
                ClipData.Item item = cd.getItemAt(0);
                String resp = item.coerceToText(context).toString();

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

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

                dropped.setEnabled(false);

                //if an item has already been dropped here, there will be a tag
                final Object tag = dropTarget.getTag();

                LayoutInflater li = LayoutInflater.from(context);
                View promptsView = li.inflate(R.layout.ns_scoop_dialog, null);

                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                        context);

                // set prompts.xml to alertdialog builder
                alertDialogBuilder.setView(promptsView);

                final EditText userInput = (EditText) promptsView
                        .findViewById(R.id.edit1);

                // set dialog message
                alertDialogBuilder
                        .setIcon(R.mipmap.ic_launcher)
                        .setTitle(dropped.getTag().toString())
                        .setCancelable(false)
                        .setPositiveButton("OK",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog,int id) {
                                        // get user input and set it to result
                                        // edit text
                                        String inAmt = userInput.getText().toString();

                                        CreateSmoothie.nsList.add(inAmt + " Green Scoops " + dropped.getTag().toString());
                                        Log.d(TAG, inAmt + " Green Scoops " + dropped.getTag().toString() + " added to list");

                                        dialog.dismiss();

                                        //dropped.setEnabled(true);
                                    }
                                })
                        .setNegativeButton("Cancel",
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        dialog.cancel();

                                        int existingID = dropped.getId();

                                        //set the original view visible again
                                        ((Activity) context).findViewById(existingID).setVisibility(View.VISIBLE);

                                        dropped.setEnabled(true);

                                    }
                                });

                // create alert dialog
                AlertDialog alertDialog = alertDialogBuilder.create();

                // show it
                alertDialog.show();
                //Button nButton = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
                //nButton.setBackgroundColor(Color.GREEN);
                //Button pButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
                //pButton.setBackgroundColor(Color.GREEN);

                if(tag!=null)
                {
                    //the tag is the view id already dropped here
                    int existingID = (Integer)tag;

                    //set the original view visible again
                    ((Activity) context).findViewById(existingID).setVisibility(View.VISIBLE);
                }

                break;
            case DragEvent.ACTION_DRAG_ENDED:

                if(DEBUG) Log.i("drag event", "ended::" + ChoiceTouchListener.offsetX + "," + ChoiceTouchListener.offsetY);

                /**
                 * returning false so that goes to parentView onDrag function
                 */
                return false;
            //break;
            default:
                break;
        }
        return true;
    }

}

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41183214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档