错误:此片段应提供默认构造函数(不带参数的公共构造函数)

Ore*_*reo 15 java android android-studio

我的课程扩展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()));
    }

}
Run Code Online (Sandbox Code Playgroud)

这就是我在Activity中使用它的方式:

public void showDatePickerDialog(View v) {
        new DatePickerFragment((EditText) v).show(getSupportFragmentManager(), "datePicker");
    }
Run Code Online (Sandbox Code Playgroud)

并且这样打电话:

    <EditText
        android:id="@+id/editDate"
        android:onClick="showDatePickerDialog" />
Run Code Online (Sandbox Code Playgroud)

但我总是得到:

Error: This fragment should provide a default constructor (a public constructor with no arguments)
Run Code Online (Sandbox Code Playgroud)

Dei*_*zan 23

较新版本的Android SDK会强制您获得一个空的无参数构造函数.这是一个很好的做法.这允许您将实例状态保存到bundle中,Android将重新创建调用默认构造函数的片段.

在这种情况下,您有以下解决方案:

首先,创建默认构造函数:

public DatePickerFragment() {}
Run Code Online (Sandbox Code Playgroud)

创建实例并通过setter方法设置EditText:

DatePickerFragment fragment = new DatePickerFragment();
fragment.setEditText(v); // create this setter
fragment.show();
Run Code Online (Sandbox Code Playgroud)

由于EditText是parcelable,您还可以设置为参数:

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");
Run Code Online (Sandbox Code Playgroud)

[编辑] 根据建议,尝试忽略这样的错误配置build.gradle:

lintOptions { 
  abortOnError false 
  checkReleaseBuilds false 
} 
Run Code Online (Sandbox Code Playgroud)

这不会通过在片段中使用非默认构造函数来停止应用程序的构建.


inm*_*yth 5

你需要删除这个构造函数

public DatePickerFragment(EditText editText) {
    editDate = editText;
}
Run Code Online (Sandbox Code Playgroud)

您不应该将 View 引用传递给 Fragment。如果您想更新 Activity 或其他地方的 EditText,请使用侦听器。

  • 首先,您不应该自定义 Fragment 构造函数,期间。[http://stackoverflow.com/questions/10450348/do-fragments-really-need-an-empty-constructor]。并且您应该只将数据传递给 Fragment,而不是 View。为什么 ?因为生命周期。当运行更新视图的长进程(如rest api)时,视图可能已经消失,因为保存它的活动或片段已被销毁。这将为您提供 Null Pointer Exc。因此视图交互应该通过空检查与侦听器完成。但今天更好的方法是使用事件总线/奥托库。 (2认同)