0

My second question for android development (using android studio) of the app I'm currently suffering through. To elaborate:

The Aim: Two arrows, one up, one down. Above and below a box that contains information that is each time different.

The Problem: Here I try to set up conditionals based off a variable that I set first to be 0. If the up arrow is pressed and that variable is 0, do nothing, otherwise decrement that number. Likewise, if the down arrow is press and the variable is 9 do nothing, otherwise increment that number.

So this is what happens. My code:

package com.example.savag.myapplication;

import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.media.Image;
import android.provider.Settings;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SensorEventListener{


    //Define the sensor Manager
    SensorManager sm;

    //Define the Motion Sensor objects
    Sensor accelerometer;
    Sensor gravity;
    Sensor gyroscope;
    //Sensor uncalgyro;
    Sensor lineaccel;
    Sensor rotatevector;
    //Sensor sigmotion;
    //Sensor stepcounter;
    //Sensor stepdetector;
    //Define the changing Motion Sensor text values
    TextView gyrosense;
    //TextView uncalgyrosense;
    TextView acceleration;
    TextView gravitysense;
    TextView lineaccelsense;
    TextView rotatesense;
    //TextView sigmotionsense; //In order to make use of this, use onTrigger event
    //TextView stepstaken;
    //TextView stepdetected; //In order to make use of this, use onTrigger event

    //Define the position sensor objects
    Sensor gamerotatevector;

    //Define the changing Position sensor objects
    TextView gamerotatesense;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //variable declare
        final ImageButton button1 = (ImageButton)findViewById(R.id.motbut_unpressed);
        final ImageView topbar2 = (ImageView)findViewById(R.id.topbarmain);
        final ImageButton button2 = (ImageButton)findViewById(R.id.posbut_unpressed);
        final ImageButton button3 = (ImageButton)findViewById(R.id.envbut_unpressed);
        final LinearLayout andfield = (LinearLayout)findViewById(R.id.babcocklayout);
        final ImageButton arrowup = (ImageButton)findViewById(R.id.uparrow);
        final ImageButton arrowdown = (ImageButton)findViewById(R.id.downarrow);
        final ImageView navbar = (ImageView)findViewById(R.id.infospace);
        int counter;
        counter = 0;
        final String strcounter;
        strcounter = Integer.toString(counter);
        //Set Nav bar invisible for now
        arrowup.setVisibility(View.GONE);
        arrowdown.setVisibility(View.GONE);
        navbar.setVisibility(View.GONE);

        button1.setOnClickListener( //This is for the motion button
                new ImageButton.OnClickListener() {
                    public void onClick(View v) {
                        button1.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.motionbutton_pressed, null));
                        topbar2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.topbarmotion, null));
                        ndfield.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.logoandbarmotion, null));
                        //make sure the other two buttons are normal again
                        button2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.positionbutton_normal, null));
                        button3.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.envirobutton_normal, null));
                        //make the arrows and infospace appear
                        arrowup.setVisibility(View.VISIBLE);
                        arrowdown.setVisibility(View.VISIBLE);
                        navbar.setVisibility(View.VISIBLE);
                    }
                }
        );
        button2.setOnClickListener( //This is for the position button
                new ImageButton.OnClickListener(){
                    public void onClick(View v){
                        button2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.positionbutton_pressed, null));
                        topbar2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.topbarposition, null));
                        andfield.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.logoandbaralternate, null));
                        //make sure the other two buttons are normal again
                        button1.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.motionbutton_normal, null));
                        button3.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.envirobutton_normal, null));
                        arrowup.setVisibility(View.VISIBLE);
                        arrowdown.setVisibility(View.VISIBLE);
                        navbar.setVisibility(View.VISIBLE);
                    }
                }
        );
        button3.setOnClickListener( //This is for the environment button
                new ImageButton.OnClickListener(){
                    public void onClick(View v){
                        button3.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.envirobutton_pressed, null));
                        topbar2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.topbarenviro, null));
                        andfield.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.logoandbaralternate, null));
                        //make sure the other two buttons are normal again
                        button1.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.motionbutton_normal, null));
                        button2.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.positionbutton_normal, null));
                        arrowup.setVisibility(View.VISIBLE);
                        arrowdown.setVisibility(View.VISIBLE);
                        navbar.setVisibility(View.VISIBLE);
                    }
                }
        );
        arrowup.setOnClickListener( //This is for the environment button
                new ImageButton.OnClickListener(){
                    public void onClick(View v){
                        if (strcounter.equals("0"))
                        {
                        }
                        else
                        {
                            counter--; //how many times
                            strcounter = Integer.toString(counter);
                            //et1.setText(strcounter);
                            //now lets set text accordingly
                            if (strcounter.equals("1")) {

                            }

                        }

                        }
                    });
                }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    @Override
    public void onSensorChanged(SensorEvent event) {

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

So we run this and we get this error: "local variable counter is accessed within inner class; needs to be declared final" However I DO NOT want this, as this is essentially me promising I'm going to do nothing with this variable. Which is a lie, I want to do everything to this variable. Also final int doesn't bloody work either.
I can't solve the damned problem. Okay so then I think, global variable then. Nope, doesn't work either.
can someone please shed some light. Many thanks in advance.

8
  • 1
    I suggest that you edit your question to remove the ranting and add the actual code. This is not valid Java code; you would be getting many more compile errors if this is actually what is in your editor. We cannot help you fix code that we cannot see. Commented Sep 29, 2015 at 22:01
  • ? That is the code. But i'll add the parts that were omitted, which were genuinely nothing to do with the problem of the code. My point was that unless that part is fixed.. I cannot add code in that part that does something. deleted the attempts at humour and added all. :] Commented Sep 29, 2015 at 22:15
  • possible duplicate of non-final variable in a onClickListener Commented Sep 29, 2015 at 22:16
  • As suggested in the dupe, refactor the local int counter variable as a member variable (a.k.a global variable, a.k.a field) private int counter = 0;. Commented Sep 29, 2015 at 22:20
  • @MickMnemonic: A member variable is not a global variable. Commented Sep 29, 2015 at 22:20

3 Answers 3

1

As the error message indicates, counter is a local variable inside of your onCreate() method. It goes away as soon as onCreate() ends. That is why you cannot reference it from the inner classes.

Move it to be a field (a.k.a., data member, member variable) of the class, alongside all your other fields:

public class MainActivity extends AppCompatActivity implements SensorEventListener{
  int counter=0;

  //Define the sensor Manager
  SensorManager sm;

  //Define the Motion Sensor objects
  Sensor accelerometer;
  Sensor gravity;

  // and so on
Sign up to request clarification or add additional context in comments.

Comments

1

put this code (inner class ) inside your activity class :

private class MyImageButton  extends ImageButton{

private int myCounter=0;
private String myStrCounter=Integer.toString(myCounter);
public MyImageButton(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}




    arrowup.setOnClickListener( //This is for the environment button
            new MyImageButton.OnClickListener(){
                public void onClick(View v){
                    if (myStrCounter.equals("0"))
                    {
                    }
                    else
                    {
                        myCounter--; //how many times
                        myStrCounter = Integer.toString(myCounter);

                        //now lets set text accordingly
                        if (myStrCounter.equals("1")) {

                        }

                    }

                    }
                });

3 Comments

Thank you for the quick reply, this flagged the error, "modifier private not allowed here"
Awesome, three ways to do it. Thank you for the clarification
welocme bro , i hope that your problem have been solved
1

This code you have isn't right Code. I assume it must be inside the oncreate . If so it is just a normal stackvariable and no global object.

Edit Like I said and having now seen your whole code: the variable counter must be global and not local inside onCreate()

Thats why AS want to tell you htat it needs a final variabel.

Quote from official Java Docs:

"In addition, a local class has access to local variables. However, a local class can only access local variables that are declared final."

You see that your counter is a local variable and not global

3 Comments

But in your Code the counter is still local inside onCreate() method
nevermind but I told you that if it is like I assumed inside onCreate (and it turned out to be) that it is a normal stackvariable and not a global one....but like I said nevermind if it was too confusing for you to understand
@IljaKO the OP is entitled to choose whatever answer they wish as accepted - if they felt another was more helpful to them, then that's their choice. Don't worry about it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.