开发者

Android: circle drawing and touch event error

I am having an issue right now with drawing circles and handling touch events. Basically I am listening for touch events, which selects a circle and lets a user drag around to control the location/radius of the circle. I also have a menu option to "add a new circle" which changes the drag event to add a new circle to view. This keeps throwing a force close though when I test it. I do not know how to see what is causing the force close (sorry I am a newb who happens to be good at hacking things apart and making them work). Could someone please take a look at this, or point me in the direction of debugging this correctly?

I think it might have something to do with the new circle b开发者_运维知识库eing created inside the view that is currently in focus? If that makes any sense.

Here is my code... initial values are coming from a previous activity (this is not where the problem lies though, the problem is in my 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;
}

}

Thank you for those who respond.


The first thing you need to learn when developing android apps is to read the logcat : http://developer.android.com/guide/developing/tools/adb.html#logcat

Please, connect your device to the PC and run adb logcat *:W > log.txt
Read the output and look for any exception thrown. Then, paste here the code so we have a better idea of what's going on.

PS: If you're testing on the emulator from Eclipse, the android debug perspective will open one window with the logcat for you. Use it to copy the relevant text. It will be the full logcat, so it will have a lot more non-relavant output than the command line above.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜