如何将自定义按钮添加到 material 日期范围选择器 android?
How to add custom button to material date range picker android?
如何向 material 日期范围选择器添加自定义按钮?
我正在尝试获取对话框的视图,以便我可以通过编程方式添加按钮,但我无法从选择器中获取任何视图。
MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
.setTitleText("Select Dates")
.build();
dateRangeTV.setOnClickListener(v -> {
materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");
View root = materialDatePicker.requireView();
});
但是我说的是错误的。
java.lang.IllegalStateException: Fragment MaterialDatePicker{e52ecfc} (40593b4f-a55a-4d6c-aa3b-2b778e721149 tag=DATE_PICKER) did not return a View from onCreateView() or this was called before onCreateView().
在这个例子中,我创建了一个 class MainActivity.java
,它的布局从 Button
打开自定义对话框,如下所示:
MainActivity.java
:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Button openDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
openDialog = findViewById(R.id.open_dialog);
openDialog.setOnClickListener(v -> {
Log.d(TAG, "onClick: opening dialog.");
MyCustomDialog dialog = new MyCustomDialog();
dialog.show(getSupportFragmentManager(), "MyCustomDialog");
});
}
}
Layout
与 Button
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="MainActivity">
<Button
android:id="@+id/open_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="20sp"
android:text="open dialog" />
</RelativeLayout>
并且 MyCustomDialog.java
class 扩展了 DialogFragment
以具有自定义视图来存储 DatePicker
以及其中的其他 Widgets
。 (例如 TextView
):
public class MyCustomDialog extends DialogFragment {
private static final String TAG = "MyCustomDialog";
private TextView mActionOk, mActionCancel;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_my_custom, container, false);
mActionCancel = view.findViewById(R.id.action_cancel);
mActionOk = view.findViewById(R.id.action_ok);
mActionCancel.setOnClickListener(v -> {
Log.d(TAG, "onClick: closing dialog");
getDialog().dismiss();
});
mActionOk.setOnClickListener(v -> {
Log.d(TAG, "onClick: capturing input");
getDialog().dismiss();
});
return view;
}
}
最后但并非最不重要的 XML
文件 dialog_my_custom.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="550dp"
android:padding="10dp">
<TextView
android:id="@+id/heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="This is your custom View with DatePicker"
android:textAlignment="center"
android:textColor="#000"
android:textSize="18sp" />
<DatePicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/heading"
android:layout_centerHorizontal="true" />
<RelativeLayout
android:id="@+id/frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/date_picker">
<TextView
android:id="@+id/action_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:text="OK"
android:textColor="#33bbff"
android:textSize="18sp" />
<TextView
android:id="@+id/action_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:text="CANCEL"
android:textColor="#33bbff"
android:textSize="18sp" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
不要忘记添加支持库的dependency
:
implementation "com.android.support:appcompat-v7:$supportLibVersion"
结果:
发生此错误是因为 materialDatePicker.show()
是异步调用,并且 MaterialDatePicker
(DialogFragment) 尚未创建,无法访问其根视图。为避免此错误,您必须通过添加 DefaultLifecycleObserver
使用 materialDatePicker.getLifecycle()
侦听 DialogFragment Lifecycle
并使用覆盖方法 void onStart(@NonNull LifecycleOwner owner)
访问 MaterialDatePicker
根从那里查看。
将您的代码更改为如下所示:
MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
.setTitleText("Select Dates")
.build();
materialDatePicker.getLifecycle().addObserver(new DefaultLifecycleObserver()
{
@Override
public void onCreate(@NonNull LifecycleOwner owner) {}
@Override
public void onStart(@NonNull LifecycleOwner owner) {
//in onStart of DialogFragment the View has been created so you can access the materialDatePicker.requireView()
View root = materialDatePicker.requireView();
//from root find the View you are interested to add your custom button
}
@Override
public void onResume(@NonNull LifecycleOwner owner) {}
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
//remove Lifecycle Observer
materialDatePicker.getLifecycle().removeObserver(this);
}
});
materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");
如何向 material 日期范围选择器添加自定义按钮?
我正在尝试获取对话框的视图,以便我可以通过编程方式添加按钮,但我无法从选择器中获取任何视图。
MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
.setTitleText("Select Dates")
.build();
dateRangeTV.setOnClickListener(v -> {
materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");
View root = materialDatePicker.requireView();
});
但是我说的是错误的。
java.lang.IllegalStateException: Fragment MaterialDatePicker{e52ecfc} (40593b4f-a55a-4d6c-aa3b-2b778e721149 tag=DATE_PICKER) did not return a View from onCreateView() or this was called before onCreateView().
在这个例子中,我创建了一个 class MainActivity.java
,它的布局从 Button
打开自定义对话框,如下所示:
MainActivity.java
:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Button openDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
openDialog = findViewById(R.id.open_dialog);
openDialog.setOnClickListener(v -> {
Log.d(TAG, "onClick: opening dialog.");
MyCustomDialog dialog = new MyCustomDialog();
dialog.show(getSupportFragmentManager(), "MyCustomDialog");
});
}
}
Layout
与 Button
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="MainActivity">
<Button
android:id="@+id/open_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="20sp"
android:text="open dialog" />
</RelativeLayout>
并且 MyCustomDialog.java
class 扩展了 DialogFragment
以具有自定义视图来存储 DatePicker
以及其中的其他 Widgets
。 (例如 TextView
):
public class MyCustomDialog extends DialogFragment {
private static final String TAG = "MyCustomDialog";
private TextView mActionOk, mActionCancel;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dialog_my_custom, container, false);
mActionCancel = view.findViewById(R.id.action_cancel);
mActionOk = view.findViewById(R.id.action_ok);
mActionCancel.setOnClickListener(v -> {
Log.d(TAG, "onClick: closing dialog");
getDialog().dismiss();
});
mActionOk.setOnClickListener(v -> {
Log.d(TAG, "onClick: capturing input");
getDialog().dismiss();
});
return view;
}
}
最后但并非最不重要的 XML
文件 dialog_my_custom.xml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="550dp"
android:padding="10dp">
<TextView
android:id="@+id/heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:text="This is your custom View with DatePicker"
android:textAlignment="center"
android:textColor="#000"
android:textSize="18sp" />
<DatePicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/heading"
android:layout_centerHorizontal="true" />
<RelativeLayout
android:id="@+id/frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/date_picker">
<TextView
android:id="@+id/action_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:text="OK"
android:textColor="#33bbff"
android:textSize="18sp" />
<TextView
android:id="@+id/action_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:text="CANCEL"
android:textColor="#33bbff"
android:textSize="18sp" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
不要忘记添加支持库的dependency
:
implementation "com.android.support:appcompat-v7:$supportLibVersion"
结果:
发生此错误是因为 materialDatePicker.show()
是异步调用,并且 MaterialDatePicker
(DialogFragment) 尚未创建,无法访问其根视图。为避免此错误,您必须通过添加 DefaultLifecycleObserver
使用 materialDatePicker.getLifecycle()
侦听 DialogFragment Lifecycle
并使用覆盖方法 void onStart(@NonNull LifecycleOwner owner)
访问 MaterialDatePicker
根从那里查看。
将您的代码更改为如下所示:
MaterialDatePicker.Builder<Pair<Long,Long>> builder = MaterialDatePicker.Builder.dateRangePicker();
MaterialDatePicker<Pair<Long,Long>> materialDatePicker = builder
.setTitleText("Select Dates")
.build();
materialDatePicker.getLifecycle().addObserver(new DefaultLifecycleObserver()
{
@Override
public void onCreate(@NonNull LifecycleOwner owner) {}
@Override
public void onStart(@NonNull LifecycleOwner owner) {
//in onStart of DialogFragment the View has been created so you can access the materialDatePicker.requireView()
View root = materialDatePicker.requireView();
//from root find the View you are interested to add your custom button
}
@Override
public void onResume(@NonNull LifecycleOwner owner) {}
@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
//remove Lifecycle Observer
materialDatePicker.getLifecycle().removeObserver(this);
}
});
materialDatePicker.show(getSupportFragmentManager(), "DATE_PICKER");