简体   繁体   中英

Android app, can't refer to a non final variable but don't want to make it final

Hello stackoverflow users,

I have a problem, I have a variable named counter that is inscrementing or decrementing by 2 buttons, this variable is displayed with 2 TextViews.The problem is that the variable need to be setted local not global ( global is working, but I use inflation to duplicate the layer many times, if he is global, when I increment or decrement the value of a layout he modify in every layout )

The error is this:

Description Resource    Path    Location    Type
Cannot refer to a non-final variable counter inside an inner class defined in a different method    Tabel.java  /Instances_temperature/src/com/example/instances_temperature    line 67 Java Problem

Line 67 would be this:

if( mAutoIncrement && counter < 35)

If I set the variable final it can't be accesed by decrementing ( counter-- ) or incrementing ( counter++ )

Hope I explained the program how it work for the moment, thank you for your helping.

Below is my code of the java file:

public class Tabel extends ActionBarActivity {

    int i;

    int value; // Ignore this, this is the number that is taked from mainactivity for Inflation
    //int counter=20; // counter default value for start = 20

    static int REP_DELAY = 50; // Constant value for long click update
    private Handler repeatUpdateHandler = new Handler();
    private boolean mAutoIncrement = false;
    private boolean mAutoDecrement = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tabel);
        Intent intentObject = getIntent();
        value = intentObject.getIntExtra("max", 0);
        LinearLayout layout = (LinearLayout)findViewById(R.id.container2);


        for(i=1;i<=value;i++)
        {
            LayoutInflater layoutinflate = null; 
            layoutinflate = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
            final View rowview = layoutinflate.inflate( R.layout.inflation_layout, null);

            Button add,sub;
            final TextView display;
            final TextView showup;

            int counter = 20;

            add = (Button) rowview.findViewById(R.id.plus);
            sub = (Button) rowview.findViewById(R.id.minus);
            display = (TextView) rowview.findViewById(R.id.showtemp);
            showup = (TextView) rowview.findViewById(R.id.showvalue);

            class RptUpdater implements Runnable {
                public void run() {
                    if( mAutoIncrement && counter < 35){
                        //increment();
                        if(counter<35)
                        {
                        counter++;
                        display.setText( "" + counter+"°C");
                        showup.setText(" "+counter+"°C ");
                        }
                        else
                        {
                            Context context = getApplicationContext();
                            CharSequence text = "Maximum value is 35°C!";
                            int duration = Toast.LENGTH_SHORT;
                            final Toast toast = Toast.makeText(context, text, duration);
                            toast.show();
                            toast.setGravity(Gravity.TOP, 0, 100);
                        }
                        repeatUpdateHandler.postDelayed( new RptUpdater(), REP_DELAY );
                    } 
                    else

                        if( mAutoDecrement && counter > 10){
                       // decrement();
                            if(counter>10)
                            {
                            counter--;
                            display.setText( "" + counter+"°C");
                            showup.setText(" "+counter+"°C ");
                            repeatUpdateHandler.postDelayed( new RptUpdater(), REP_DELAY );
                            }
                            else
                            {
                                Context context = getApplicationContext();
                                CharSequence text = "Minimum value is 10°C!";
                                int duration = Toast.LENGTH_SHORT;
                                final Toast toast = Toast.makeText(context, text, duration);
                                toast.show();
                                toast.setGravity(Gravity.BOTTOM, 0, 50);
                            }
                        }

                }
            }


            showup.setText(" "+counter+"°C ");
            display.setText(""+counter+"°C");
            add.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
            if(counter<35){
                counter++;
                display.setText( "" + counter+"°C ");
                showup.setText(" "+counter+"°C ");
                }
            else{
                Context context = getApplicationContext();
                CharSequence text = "Maximum value is 35°C!";
                int duration = Toast.LENGTH_SHORT;
                final Toast toast = Toast.makeText(context, text, duration);
                toast.show();
                toast.setGravity(Gravity.TOP, 0, 100);
                }
            }
        });

        sub.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {

            if(counter>10){
                counter--;
                display.setText( "" + counter+"°C");
                showup.setText(" "+counter+"°C ");
                }
            else{
                Context context = getApplicationContext();
                CharSequence text = "Minimum value is 10°C!";
                int duration = Toast.LENGTH_SHORT;
                final Toast toast = Toast.makeText(context, text, duration);
                toast.show();
                toast.setGravity(Gravity.BOTTOM, 0, 50);
            }
            }

        });
        add.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                mAutoIncrement = true;
                repeatUpdateHandler.post(new RptUpdater() );
                return false;
            }
        });
        add.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                if( (event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL) && mAutoIncrement )
                    mAutoIncrement = false;
                    return false;
            }
        });
        sub.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                mAutoDecrement = true;
                repeatUpdateHandler.post(new RptUpdater() );
                return false;
            }
        });
        sub.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                if( (event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL) && mAutoDecrement )
                    mAutoDecrement = false;
                    return false;
            }
        });



            layout.addView(rowview);
        }



        //showvalue.setText(String.valueOf(getIntent().getExtras().getInt("max")));


        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.tabel, menu);
        return true;
    }

    @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();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_tabel,
                    container, false);
            return rootView;
        }
    }

    protected void onSaveInstanceState(Bundle savedInstance) {
           super.onSaveInstanceState(savedInstance); 
           //savedInstance.putInt("myCounter",counter); 
           }

}

If you want a dirty fix. Make counter a final int[] counter = {20} and then when you want to access it just call counter[0]

Use AtomicInteger rather than int. This means you can set the variable to be final, and still increment it by calling methods on it.

it is the Java specification. why not keep a "counter" filed in RptUpdater class.

the variables that you want to use , which android says to make it final . declare those variables here. than android will not give warning to make it as final

public class Tabel extends ActionBarActivity {


int counter = 20;
TextView display;
TextView showup;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM