Android:圆形绘图和触摸事件错误

时间:2011-04-23 04:13:18

标签: android events geometry touch

我现在遇到问题,画圈和处理触摸事件。基本上我正在听触摸事件,它选择一个圆圈并让用户拖动来控制圆的位置/半径。我还有一个“添加新圆圈”的菜单选项,可以更改拖动事件以添加要查看的新圆圈。当我测试时,这会使力量接近。我不知道如何看到导致力量关闭的原因(对不起,我是一个擅长将事情分开并让它们起作用的新手)。有人可以看看这个,还是指出我正确调试的方向?

我认为这可能与目前关注的视图中创建的新圈子有关?如果这是有道理的。

这是我的代码......初始值来自之前的活动(这不是问题所在,问题出在我的TouchEventListener中)。

/*this is the working example of playing audio
* and adjusting the volume, although playback
* is a bit choppy and the different sounds loose
* sync after a bit
*/

package com.adam.PlaySound;

import java.util.ArrayList;
import java.util.Collections;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.AbsoluteLayout;
import android.widget.TextView;

@SuppressWarnings("deprecation")
public class EditInterface extends Activity {
/** Called when the activity is first created. */

/*do our web stuff*/
ConnectToUrl makeConnection = new ConnectToUrl();

TextView text;
AbsoluteLayout circlesView;
int numPlayers;
ArrayList<Float> regionX = new ArrayList<Float>();
ArrayList<Float> regionY = new ArrayList<Float>();
ArrayList<Float> regionR = new ArrayList<Float>();
ArrayList<String> soundFiles = new ArrayList<String>();
ArrayList<LoopRegion> region = new ArrayList<LoopRegion>();
ArrayList<LoopRegion> border = new ArrayList<LoopRegion>();
MediaPlayer mediaPlayer = new MediaPlayer();
String key;
int index;
int actionState = 0;

//We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit);

    text = (TextView) findViewById(R.id.text);
    text.setText("");
    circlesView = (AbsoluteLayout) findViewById(R.id.absoluteLayout1);
    circlesView.setOnTouchListener(Motion);

    Bundle extras = getIntent().getExtras(); 
    if(extras != null) {
        numPlayers = extras.getInt("numPlayers");
    }

    for (int i = 0; i < numPlayers; i++){
        //get regionX values
        key = "regionX" + i;
        regionX.add(extras.getFloat(key));
        //get regionY values
        key = "regionY" + i;
        regionY.add(extras.getFloat(key));
        //get regionR values
        key = "regionR" + i;
        regionR.add(extras.getFloat(key));
        //get soundFiles values
        key = "soundFiles" + i;
        soundFiles.add(extras.getString(key));

        //add our circles
        region.add(new LoopRegion(this,regionX.get(i),regionY.get(i),regionR.get(i), true, Color.WHITE));
        border.add(new LoopRegion(this,regionX.get(i),regionY.get(i),regionR.get(i), false, Color.RED));
        circlesView.addView(region.get(i));
        circlesView.addView(border.get(i));

    }

}   

OnTouchListener Motion
= new AbsoluteLayout.OnTouchListener(){
@Override
    public boolean onTouch(View v, MotionEvent ev) {
        float x1 = ev.getX(0);
        float y1 = ev.getY(0);
        float x2 = ev.getX(1);
        float y2 = ev.getY(1);
        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            if (actionState == 0){
                /***select our circle***/
                mode = DRAG;
                //for testing//text.setText("action down");

                //calculate distance to detect which circle we will look at
                ArrayList<Float> distance = new ArrayList<Float>();
                for (int i = 0; i < numPlayers; i++){
                    if (distance(regionX.get(i), regionY.get(i), x1, y1) > (regionR.get(i) + 5)){
                        distance.add((float) 10000);
                    }
                    else {
                        distance.add(distance(regionX.get(i), regionY.get(i), x1, y1));
                    }
                }
                Object object = Collections.min(distance);
                index = distance.indexOf(object);

                //for testing//text.setText("index: " + index);

                //set up sound
                String path = "http://soundclusters.adamlaskowitz.com/uploads/" + soundFiles.get(index);
                mediaPlayer = MediaPlayer.create(EditInterface.this, Uri.parse(path));
                mediaPlayer.start();

                region.get(index).setColor(true, Color.RED);
                region.get(index).invalidate();
                border.get(index).setColor(false, Color.WHITE);
                border.get(index).invalidate();
            }
            else if (actionState == 1){
                region.add(new LoopRegion(EditInterface.this, x1, y1, 50 , true, Color.WHITE));
                border.add(new LoopRegion(EditInterface.this,  x1, y1, 50, false, Color.RED));

                circlesView.addView(region.get(numPlayers));
                circlesView.addView(border.get(numPlayers));
                circlesView.clearFocus();
                /////region.get(index).invalidate();
            /////border.get(index).invalidate();
                index = numPlayers; //since they are zero-indexed the previous
                //amount of Players will equal the index of the new larger array
                numPlayers = region.size();
                text.setText("length:" + numPlayers + ", state:" + actionState);
                //text.setText("index:" + index + ", numPlayers:" + numPlayers + ", length:" + region.size());
            }

            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            /***initiate zoom***/
            mode = ZOOM;
            //for testing//text.setText("action 2 down");

            break;

        case MotionEvent.ACTION_UP:
            /***finish our current edit and deselect circle***/
            mode = NONE;
            //for testing//text.setText("action up");

            //stop and release current sound for region
            mediaPlayer.stop();
            mediaPlayer.release();

            region.get(index).setColor(true, Color.WHITE);
            region.get(index).invalidate();
            border.get(index).setColor(false, Color.RED);
            border.get(index).invalidate();

            actionState = 0;

            text.setText("index:" + index + ", state:" + actionState);

            break;
        case MotionEvent.ACTION_POINTER_UP:
            /***set mode Drag***/
            mode = DRAG;
            //for testing//text.setText("action 2 up");

            break;

        case MotionEvent.ACTION_MOVE:               
            if (mode == DRAG){
                /***Drag the circle based on radius***/
                //for testing//text.setText("action move");
                region.get(index).setCoordinate(x1, y1, regionR.get(index));
                region.get(index).invalidate();
                border.get(index).setCoordinate(x1, y1, regionR.get(index));
                region.get(index).invalidate();
                regionX.set(index, x1);
                regionY.set(index, y1);

            }
            else if (mode == ZOOM) {
                /***Zoom and move the circle***/
                //for testing//text.setText("action 2 move");
                regionR.set(index, distance(x1,y1,x2,y2));
                float centerX = midpoint(x1,x2);
                float centerY = midpoint(y1,y2);
                float radius = regionR.get(index)/2;
                region.get(index).setCoordinate(centerX, centerY, radius);
                region.get(index).invalidate();
                border.get(index).setCoordinate(centerX, centerY, radius);
                region.get(index).invalidate();
                regionX.set(index, centerX);
                regionY.set(index, centerY);
                regionR.set(index, radius);
            }
            break;
        }
        return true;
    }
};

//make our menu---------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.edit_menu, menu);
    return true;
}

public float regionXNew[] = new float[numPlayers];

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    switch (item.getItemId()) {
    case R.id.play:
        //return to the GraphicInterface----------------------------------------
        Intent mIntent = new Intent(EditInterface.this, GraphicInterface.class);
        String num = Integer.toString(numPlayers);
        String xVal = "";
        String yVal = "";
        String rVal = "";
        String files = "";
        for (int i = 0; i < numPlayers; i++){
            //format values to send to web*/
            if (i == (numPlayers - 1)){
                xVal = xVal.concat(regionX.get(i) + "");
                yVal = yVal.concat(regionY.get(i) + "");
                rVal = rVal.concat(regionR.get(i) + "");
                files = files.concat(soundFiles.get(i) + "");
            }
            else {
                xVal = xVal.concat(regionX.get(i) + "=");
                yVal = yVal.concat(regionY.get(i) + "=");
                rVal = rVal.concat(regionR.get(i) + "=");
                files = files.concat(soundFiles.get(i) + "=");
            }
        }

        makeConnection.sendToWeb(num, xVal, yVal, rVal, files);

        if (getParent() == null) {
            setResult(RESULT_OK, mIntent);
        } else {
            getParent().setResult(RESULT_OK, mIntent);
        }
        finish();
        //return to the GraphicInterface---------------------------------------
        return true;
    case R.id.help:

        return true;
    case R.id.add:
        actionState = 1;
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}
//make our menu---------------------------------------------------------

public float distance(float x1, float y1, float x2, float y2){
    float dist;
    float a = x1 - x2;
    float b = y1 - y2;

    dist = (float) (Math.pow(a, 2) + Math.pow(b, 2));
    dist = (float) Math.sqrt(dist);

    return dist;
}

public float midpoint(float axis1, float axis2){
    float midpoint;
    midpoint = (axis1 + axis2)/2;
    return midpoint;
}

}

感谢那些回复的人。

1 个答案:

答案 0 :(得分:0)

开发Android应用时需要学习的第一件事是阅读logcathttp://developer.android.com/guide/developing/tools/adb.html#logcat

请将您的设备连接到PC并运行adb logcat *:W > log.txt
读取输出并查找抛出的任何异常。然后,在此处粘贴代码,以便我们更好地了解正在发生的事情。

PS:如果您正在使用Eclipse在模拟器上进行测试,那么android调试透视图将为您打开一个带有logcat的窗口。用它来复制相关文本。它将是完整的logcat,因此它将具有比上面的命令行更多的非相关输出。