0

Since i started programing with java on android projects, i didn't have problems where it says: Non static field cannot be referenced from a static context.

This is my code:

package com.esmad.pdm.friendlymanager;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.content.Intent;
import java.util.Calendar;
import android.media.Image;
import android.os.Build;
import android.support.annotation.IdRes;
import android.support.annotation.RequiresApi;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.TimePicker;


public class NewMatch extends AppCompatActivity {

    ImageView questionMark;
    RadioGroup radioGroup;
    EditText gameEventNameTxt;
    TextInputLayout textInputLayout;
    TextView dateHourTxt;
    public static boolean changedData = false;
    public static boolean changedHour = false;


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

        questionMark = (ImageView) findViewById(R.id.questionMark);
        questionMark.setClickable(true);

        gameEventNameTxt = (EditText)findViewById(R.id.gameEvent);
        textInputLayout = (TextInputLayout)findViewById(R.id.textInputLayout);

        radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
        int checkedRadioButtonId = radioGroup.getCheckedRadioButtonId();

        dateHourTxt = (TextView)findViewById(R.id.dateHour);

        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {

                if (checkedId == R.id.event) {
                    textInputLayout.setHint("Event name");
                }
                else{
                    textInputLayout.setHint("Match name");
                }
            }
        });


    }


            public void imageClick(View view) {
                Log.d("builderH","im in the builder");
                AlertDialog.Builder builder = new AlertDialog.Builder(NewMatch.this);
                builder.setTitle("What is a event?");
                builder.setMessage("You can create a Event and a game, a Event is a list of games that can be repeated without the need to create every week a new game!");
                builder.setCancelable(false);
                builder.setPositiveButton("I got it!", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
                builder.show();
            }

    public static class TimePickerFragment extends DialogFragment
            implements TimePickerDialog.OnTimeSetListener {

        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Use the current time as the default values for the picker
            final Calendar c = Calendar.getInstance();
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);

            // Create a new instance of TimePickerDialog and return it
            return new TimePickerDialog(getActivity(), this, hour, minute,
                    DateFormat.is24HourFormat(getActivity()));
        }

        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            changedHour = true;
            if(changedHour && changedData){
                dateHourTxt
            }
        }
    }

    public void hourPicker(View view){
        DialogFragment newFragment = new TimePickerFragment();
        newFragment.show(getSupportFragmentManager(), "timePicker");
    }

    public static class DatePickerFragment extends DialogFragment
            implements DatePickerDialog.OnDateSetListener {

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            // Use the current date as the default date in the picker
            final Calendar c = Calendar.getInstance();
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH);
            int day = c.get(Calendar.DAY_OF_MONTH);

            // Create a new instance of DatePickerDialog and return it
            return new DatePickerDialog(getActivity(), this, year, month, day);
        }

        public void onDateSet(DatePicker view, int year, int month, int day) {
            changedData = true;
        }
    }

    public void datePicker(View view){
        DialogFragment newFragment = new DatePickerFragment();
        newFragment.show(getSupportFragmentManager(), "datePicker");
    }


    }

as you guys can see above i changed some data to static at initialization, but in other activities i didn't need to do that, and the same error happens for my dateHourTxt inside my onTimeSet method :S

You guys know why this is happening?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
  • [This answer on SO](http://stackoverflow.com/a/2559596/3921977) will give you a clear understanding of as to why you can't use static variables in a non- static method. – Aishwarya Tiwari Apr 14 '17 at 21:47
  • Possible duplicate of [Non-static variable cannot be referenced from a static context](http://stackoverflow.com/questions/2559527/non-static-variable-cannot-be-referenced-from-a-static-context) – Gary99 Apr 15 '17 at 01:13

2 Answers2

1

You are referencing dateHourTxt from a completely separate class, one that does not contain dateHourTxt.

Your onTimeSet() method is in TimePickerFragment. That is a static class. While its lines physically are inside of NewMatch, it has no access to regular fields on NewMatch. TimePickerFragment could just as easily be a separate Java class, in its own file. In fact, until you gain a bit more experience with Java, I recommend you do just that, to help you better visualize the separation between classes.

If you want TimePickerFragment to work with NewMatch, you need to do so using typical techniques, such as using getActivity() in the fragment to get at the NewMatch instance, so you can call methods on it.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • thank you a lot for your explanation, i understand part of OO, but never understood this static stuffs, i think now i got it, just a question, you said i can use getActivity to acces the picker from outside like a simple java class, but i didn't get very well about how can i pass the data inside and manage that –  Apr 14 '17 at 21:55
  • @FilipeCosta: `NewMatch` is a Java class. You can implement methods on that class, such as `foo()`. You can then have your `onTimeSet()` method call `((NewMatch)getActivity()).foo()`. You are welcome to have `foo()` take parameters, which `onTimeSet()` would pass in. – CommonsWare Apr 15 '17 at 12:02
  • @FilipeCosta: For example, [this sample app](https://github.com/commonsguy/cw-omnibus/tree/master/Fragments/Static) demonstrates an `OnClickListener` in a fragment calling a method on the activity that hosts the fragment. – CommonsWare Apr 15 '17 at 12:30
1

When you make nested class static, it no longer has access to the outer class non static fields. It can access only static fields. In you example solution is to use Fragment.getActivity method to access NewMatch. It should look as follows,

        if(changedHour && changedData){
            if (getActivity() != null && getActivity() instanceof NewMatch) {
              ((NewMatch)getActivity()).dateHourTxt = ...
            }
        }
marcinj
  • 48,511
  • 9
  • 79
  • 100
  • It's a particular case of the rule that no static member can directly access instance members, @Filipe Costa. – Lew Bloch Apr 14 '17 at 22:46