安卓系统:拖放图片

3

我有一个“拖放”的功能。

基本上,我们正在制作一个原型,让用户(孩子)把糖果拖到罐子里。

这些是我一直在研究的代码。

package edu.sbcc.cs123.draganddropbasic;

import android.app.*;
import android.graphics.*;
import android.os.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;

@SuppressWarnings("deprecation")
public class DragAndDropBasicActivity extends Activity implements OnTouchListener {
    private ImageView letterView;                       // The letter that the user drags.
    private ImageView emptyLetterView;              // The letter outline that the user is supposed to drag letterView to.
    private AbsoluteLayout mainLayout;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mainLayout = (AbsoluteLayout) findViewById(R.id.mainLayout);
        mainLayout.setOnTouchListener(this);
        letterView = (ImageView) findViewById(R.id.letterView);
        letterView.setOnTouchListener(this);

        emptyLetterView = (ImageView) findViewById(R.id.emptyLetterView);
    }

    private boolean dragging = false;
    private Rect hitRect = new Rect();

    @Override
    /**
     * NOTE:  Had significant problems when I tried to react to ACTION_MOVE on letterView.   Kept getting alternating (X,Y) 
     * locations of the motion events, which caused the letter to flicker and move back and forth.  The only solution I could 
     * find was to determine when the user had touched down on the letter, then process moves in the ACTION_MOVE 
     * associated with the mainLayout.
     */
    public boolean onTouch(View v, MotionEvent event) {
        boolean eventConsumed = true;
        int x = (int)event.getX();
        int y = (int)event.getY();

        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            if (v == letterView) {
                dragging = true;
                eventConsumed = false;
            }
        } else if (action == MotionEvent.ACTION_UP) {

            if (dragging) {
                emptyLetterView.getHitRect(hitRect);
                if (hitRect.contains(x, y))
                    setSameAbsoluteLocation(letterView, emptyLetterView);
            }
            dragging = false;
            eventConsumed = false;

        } else if (action == MotionEvent.ACTION_MOVE) {
            if (v != letterView) {
                if (dragging) {
                    setAbsoluteLocationCentered(letterView, x, y);
                }
            }
        }

        return eventConsumed;

    }


    private void setSameAbsoluteLocation(View v1, View v2) {
        AbsoluteLayout.LayoutParams alp2 = (AbsoluteLayout.LayoutParams) v2.getLayoutParams();
        setAbsoluteLocation(v1, alp2.x, alp2.y);
    }


    private void setAbsoluteLocationCentered(View v, int x, int y) {
        setAbsoluteLocation(v, x - v.getWidth() / 2, y - v.getHeight() / 2);
    }


    private void setAbsoluteLocation(View v, int x, int y) {
        AbsoluteLayout.LayoutParams alp = (AbsoluteLayout.LayoutParams) v.getLayoutParams();
        alp.x = x;
        alp.y = y;
        v.setLayoutParams(alp);
    }
}

这些是针对main.xml的内容。

<?xml version="1.0" encoding="utf-8"?>


<AbsoluteLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/mainLayout">

<ImageView 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:id="@+id/emptyLetterView" 
    android:src="@drawable/candy" 
    android:layout_x="200px" 
    android:layout_y="300px"></ImageView>

<ImageView 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:id="@+id/letterView" 
    android:src="@drawable/candy1" >

</ImageView>
</AbsoluteLayout>

然而,我希望添加其他糖果以进行拖动。我该如何实现这个功能?

你只有两颗糖果,其他的糖果是什么意思?你能详细说明一下你想要什么吗? - cjds
哦,抱歉。在那段代码中,我试图使“candy1”是可拖动的物体,“candy”是放置位置。所以我想要添加另一个糖果,比如说“candy2”,它具有与“candy1”相同的功能(也可以被拖动)。我已经进行了相同的操作,即将android:id指定为“@+id/letterView”,但没有任何效果。它甚至无法被拖动。 - Gold Skull with Pattern
换句话说,它只能处理一种糖果。我应该如何编辑代码以使其能够处理多种糖果? - Gold Skull with Pattern
1个回答

2

好的,既然你是初学者,我会详细地解释一下。

你选择的方法并不适合你所尝试的内容,你最好使用自定义视图并使用Canvas。

但是,你仍然可以通过这种方法实现你想要的效果(而且避免了重新编写代码)。

问题在于你只有一个ImageView,而你需要多个实例。

因此,既然你需要多个实例,请先动态创建它们,从你的XML文件中删除糖果,然后按照以下代码操作:

ImageView[] candies = new ImageView[10];
 for(int i=0;i<candies.length;i++){
      candies[i]=new ImageView(this);
      // TODO: Set LayoutParams for each imageView
      // i.e. AbsoluteLayout.LayoutParams imageParams1 = new AbsoluteLayout.LayoutParams(imageWidth, imageHeight); 

     candies[i].setBackgroundResource(R.drawable.candy); 
     layout.addView(candies[i], imageParams1);
}

现在您的屏幕上添加了“n”个糖果,您需要能够移动它们。
您的onTouch代码现在需要进行编辑。
现在,不再使用boolean dragging,而是将拖动变为一个int,表示正在拖动哪个视图。
此外,不再使用
setSameAbsoluteLocation(letterView, emptyLetterView);

使用

setSameAbsoluteLocation(v, emptyLetterView);

因此,代码将适用于所有监听视图(即所有糖果)。在MOUSE_UPMOUSE_DOWN中的所有letterView位置都要这样做。

现在,在您的MOUSE_MOVE中,您必须执行类似以下操作才能拖动适当的视图。

if (v != letterView) {
    if (dragging!=-1) {
        setAbsoluteLocationCentered(letterView[dragging], x, y);
     }
}

我应该把 ImageView[] candies = new ImageView[10]; 放在哪里? - Gold Skull with Pattern
在super调用之后,将其放置在onCreate中。 - cjds
Carl,我开始了一个新的问题。你能看一下吗?我已经改变了拖拽的方法。[http://stackoverflow.com/questions/14291752/image-drop-and-drag] 非常感谢你的帮助! - Gold Skull with Pattern

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接