自从我开始在android项目上使用java编程时,我没有遇到问题:非静态字段无法从静态上下文中引用。
这是我的代码:
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");
}
}
正如你们上面所见,我在初始化时将一些数据更改为静态,但在其他活动中我并不需要这样做,而且我的onTimeSet方法中的dateHourTxt也发生了同样的错误:S
你们知道为什么会这样吗?
答案 0 :(得分:1)
您从一个完全独立的类引用dateHourTxt
,该类不包含dateHourTxt
。
您的onTimeSet()
方法位于TimePickerFragment
。那是一个static
类。虽然它的行实际位于NewMatch
内,但它无法访问NewMatch
上的常规字段。 TimePickerFragment
可以很容易地成为一个单独的Java类,在它自己的文件中。事实上,在您获得更多Java经验之前,我建议您这样做,以帮助您更好地可视化类之间的分离。
如果您希望TimePickerFragment
与NewMatch
一起使用,则需要使用典型技术,例如在片段中使用getActivity()
来获取NewMatch
实例,所以你可以调用方法。
答案 1 :(得分:1)
当您使嵌套类静态时,它不再能够访问外部类非静态字段。它只能访问静态字段。在您的示例解决方案中,使用Fragment.getActivity
方法访问NewMatch
。它应该如下所示,
if(changedHour && changedData){
if (getActivity() != null && getActivity() instanceof NewMatch) {
((NewMatch)getActivity()).dateHourTxt = ...
}
}