Ошибка: этот фрагмент должен содержать конструктор по умолчанию (открытый конструктор без аргументов)
Мой класс расширяет DialogFragment
следующим образом:
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
EditText editDate;
private Calendar dateTime = Calendar.getInstance();
private SimpleDateFormat dateFormatter = new SimpleDateFormat("dd MMMM yyyy");
public DatePickerFragment(EditText editText) {
editDate = editText;
}
@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);
}
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
dateTime.set(year, monthOfYear, dayOfMonth);
editDate.setText(dateFormatter
.format(dateTime.getTime()));
}
}
И вот как я использую его в Activity:
public void showDatePickerDialog(View v) {
new DatePickerFragment((EditText) v).show(getSupportFragmentManager(), "datePicker");
}
И вызывается вот так:
<EditText
android:id="@+id/editDate"
android:onClick="showDatePickerDialog" />
Но я всегда получаю:
Error: This fragment should provide a default constructor (a public constructor with no arguments)
Ответы
Ответ 1
Новая версия Android SDK заставляет вас получить пустой конструктор no-args. Теперь это хорошая практика.
Это позволяет сохранить состояние экземпляра в комплекте, и Android воссоздает фрагмент, вызывающий конструктор по умолчанию.
В этом случае у вас есть следующие решения:
Сначала создайте конструктор по умолчанию:
public DatePickerFragment() {}
Создайте экземпляр и установите EditText с помощью метода setter:
DatePickerFragment fragment = new DatePickerFragment();
fragment.setEditText(v); // create this setter
fragment.show();
Поскольку EditText является простым, вы также можете установить в качестве аргументов:
DatePickerFragment fragment = new DatePickerFragment();
Bundle bundle = new Bundle();
bundle.putExtra("EditText", v);
fragment.setArguments(bundle); // setArguments is a method that already exists in fragments.
fragment.show(getSupportFragmentManager(), "DatePicker");
[EDIT]
Как было предложено, попробуйте проигнорировать эти ошибки, настроив build.gradle
следующим образом:
lintOptions {
abortOnError false
checkReleaseBuilds false
}
Это не остановит сборку вашего приложения, используя конструктор не по умолчанию в фрагментах.
Ответ 2
Вам нужно удалить этот конструктор
public DatePickerFragment(EditText editText) {
editDate = editText;
}
Вы не должны передавать ссылку View на Fragment. Если вы хотите обновить EditText в Activity или в другом месте, используйте прослушиватель.
Ответ 3
public DatePickerFragment() {}
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
dateTime.set(year, monthOfYear, dayOfMonth);
// editDate.setText(dateFormatter
// .format(dateTime.getTime()));
Intent intent = new Intent();
intent.setAction("CUSTOM_INTENT_FOR_SETTING_EDITTEXT");
Bundle bundle = new Bundle();
bundle.putString("my_data", dateTime.getTime.toString());
intent.putExtras(bundle);
sendBroadcast(intent);
}
public class SubmitFragment extends Fragment {
View view;
EditText editDate;
String strDate;
Button btnSubmit;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_submit, container, false);
editDate = (EditText) view.findViewById(R.id.editDate);
btnSend = (Button) view.findViewById(R.id.buttonSend);
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
strDate = editDate.getText().toString();
Log.v("strDate..... >>>", strDate);
}
});
return view;
}
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "CUSTOM_INTENT_FOR_SETTING_EDITTEXT" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("my_data");
Log.d("receiver", "message: " + message);
*****// Use this message to set Edittext here...*****
}
};
@Override
protected void onPause() {
// Unregister since the activity is about to be closed.
LocalBroadcastManager.getInstance(getactivity()).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
@Override
protected void onResume() {
// register the receiver here..
super.onResume(); LocalBroadcastManager.getInstance(getactivity()).registerReceiver(mMessageReceiver,
new IntentFilter("CUSTOM_INTENT_FOR_SETTING_EDITTEXT"));
}
}
Надеюсь, это поможет. Что именно я делаю здесь, это использование localBroadcast для
сделайте нужный... другой способ мог бы использовать интерфейс к заданному контексту
но одна неправильная вещь об этом подходе заключается в том, что когда приложение находится в фоновом режиме для
long, он вернет null, когда oncreateview будет вызван снова.
Ответ 4
Добавить @SuppressLint ( "ValidFragment" )
перед вашим классом,
открытый класс DatePickerFragment extends
Я надеюсь, что это поможет вам