Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Mario Martinez
Mario Martinez
7,097 Points

Need urgent help pleeease

So I have to do this project and I am super stuck. When i use this code, i get my 2 circles but can only spin the front circle. can anyone please help me be able to get both circles to spin on touch? I will be adding 2 more circles inside so i will reference whatever you guys use to help me to add the others. So the outside circle is supposed to spin independently on its center as well as the second circle. Below is the Java code i used as well as the XML. Please help i severely need this.

Thank you!! XML: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="6dp" tools:context="com.example.mario.degrees.MainActivity">

<ImageView
    android:id="@+id/wheel"
    android:layout_width="600dp"
    android:layout_height="600dp"
    android:scaleType="matrix"
    android:layout_centerInParent="true"/>

<ImageView
    android:id="@+id/wheel2"
    android:layout_width="600dp"
    android:layout_height="600dp"
    android:scaleType="matrix"
    android:layout_centerInParent="true"/>

</RelativeLayout>

JAVA:

package com.example.mario.degrees;

import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.graphics.Matrix; import android.widget.ImageView;

public class MainActivity extends AppCompatActivity{

// ImageView imageView; // EditText editText; // Button button; // int angle = 0; // float pivotX = 0; // float pivotY = 0;

private static Bitmap imageOriginal, imageScaled;
private static Bitmap imageOriginal2, imageScaled2;
private static Matrix matrix;
private static Matrix matrix2;

private ImageView wheel1;
private ImageView wheel2;
private int wheelHeight, wheelWidth;
private int wheelHeight2, wheelWidth2;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //load the image only once
    if(imageOriginal == null){
        imageOriginal = BitmapFactory.decodeResource(getResources(), R.drawable.first);
    }

    if(imageOriginal2 == null){
        imageOriginal2 = BitmapFactory.decodeResource(getResources(), R.drawable.second);
    }



    //initialize the matrix only once
    if(matrix == null && matrix2 == null){
        matrix = new Matrix();
        matrix2 = new Matrix();
    } else {
        //not needed, you can also post the matrix immediately to restore the old state
        matrix.reset();
        matrix2.reset();
    }

    wheel1 = findViewById(R.id.wheel);
    wheel1.setOnTouchListener(new MyOnTouchListener());
    wheel1.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            //method called more than once, but the values only need to be initialized one time
            if(wheelHeight == 0 || wheelWidth == 0){
                wheelHeight = wheel1.getHeight();
                wheelWidth = wheel1.getWidth();

                //resize
                Matrix resize = new Matrix();
                resize.postScale((float)Math.min(wheelWidth, wheelHeight) / (float)imageOriginal.getWidth(), (float)Math.min(wheelWidth, wheelHeight) / (float)imageOriginal.getHeight());
                imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false);

                //translate to the image view's center
                float translateX = wheelWidth / 2 - imageScaled.getWidth() / 2;
                float translateY = wheelHeight / 2 - imageScaled.getHeight() / 2;
                matrix.postTranslate(translateX, translateY);

                wheel1.setImageBitmap(imageScaled);
                wheel1.setImageMatrix(matrix);
            }
        }
    });
                //wheel 2
    wheel2 = findViewById(R.id.wheel2);
    wheel2.setOnTouchListener(new MyOnTouchListener2());
    wheel2.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            //method called more than once, but the values only need to be initialized one time
            if(wheelHeight2 == 0 || wheelWidth2 == 0){
                wheelHeight2 = wheel1.getHeight() - 300;
                wheelWidth2 = wheel1.getWidth() - 300;

                //resize
                Matrix resize = new Matrix();
                resize.postScale((float)Math.min(wheelWidth2, wheelHeight2) / (float)imageOriginal2.getWidth(), (float)Math.min(wheelWidth2, wheelHeight2) / (float)imageOriginal2.getHeight());
                imageScaled2 = Bitmap.createBitmap(imageOriginal2, 0, 0, imageOriginal2.getWidth(), imageOriginal2.getHeight(), resize, false);

                //translate to the image view's center
                float translateX = wheelWidth2 / 2 - imageScaled2.getWidth() / 2;
                float translateY = wheelHeight2 / 2 - imageScaled2.getHeight() / 2;
                matrix2.postTranslate(translateX, translateY);

                wheel2.setImageBitmap(imageScaled2);
                wheel2.setImageMatrix(matrix2);
            }
        }
    });

}

private class MyOnTouchListener implements View.OnTouchListener {

    private double startAngle;

    @Override
    public boolean onTouch(View v, MotionEvent event){

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                startAngle = getAngle(event.getX(), event.getY());
                break;

            case MotionEvent.ACTION_MOVE:
                double currentAngle = getAngle(event.getX(), event.getY());
                rotateWheel((float) (startAngle - currentAngle));
                startAngle = currentAngle;
                break;

            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }

    private double getAngle(double xTouch, double yTouch) {
        double x = xTouch - (wheelWidth / 2d);
        double y = wheelHeight - yTouch - (wheelHeight / 2d);

        switch (getQuadrant(x,y)){
            case 1:
                return Math.asin(y / Math.hypot(x,y)) * 180 / Math.PI;
            case 2:
                return 180 - Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
            case 3:
                return 180 + (-1 * Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);
            case 4:
                return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
            default:
                return 0;
        }
    }

}

private class MyOnTouchListener2 implements View.OnTouchListener {

    private double startAngle2;

    @Override
    public boolean onTouch(View v, MotionEvent event){

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                startAngle2 = getAngle2(event.getX(), event.getY());
                break;

            case MotionEvent.ACTION_MOVE:
                double currentAngle = getAngle2(event.getX(), event.getY());
                rotateWheel2((float) (startAngle2 - currentAngle));
                startAngle2 = currentAngle;
                break;

            case MotionEvent.ACTION_UP:
                break;
        }
        return true;
    }

    private double getAngle2(double xTouch, double yTouch) {

        double x = xTouch - (wheelWidth2 / 2d);
        double y = wheelHeight2 - yTouch - (wheelHeight2 / 2d);

        switch (getQuadrant(x,y)){
            case 1:
                return Math.asin(y / Math.hypot(x,y)) * 180 / Math.PI;
            case 2:
                return 180 - Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
            case 3:
                return 180 + (-1 * Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI);
            case 4:
                return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI;
            default:
                return 0;
        }
    }

}

/**
 * @return The selected quadrant.
 */
private static int getQuadrant(double x, double y) {
    if (x >= 0) {
        return y >= 0 ? 1 : 4;
    } else {
        return y >= 0 ? 2 : 3;
    }
}
private void rotateWheel(float degrees) {
    matrix.postRotate(degrees, wheelWidth / 2, wheelHeight / 2);
    wheel1.setImageMatrix(matrix);
}
            //wheel 2
private void rotateWheel2(float degrees) {
    matrix2.postRotate(degrees, wheelWidth2 / 2, wheelHeight2 / 2);
    wheel2.setImageMatrix(matrix2);
}

}