Android 带有时间选择器的FragmentDialog的错误行为
我正在创建一个带有自定义视图的对话框。 视图中的一个组件是时间选择器。 执行此操作时,计时器选择器的OK+Cancel按钮将控制,FragmentDialog默认按钮将禁用 这会导致一个问题,因为根据用户数据,我会显示/隐藏时间选择器视图,当它被隐藏时,它也会隐藏OK+Cancel按钮 拥有自定义视图非常重要,这样用户就可以在单个视图中选择所有相关数据 编辑-添加显示问题的图像 layout.xmlAndroid 带有时间选择器的FragmentDialog的错误行为,android,timepicker,Android,Timepicker,我正在创建一个带有自定义视图的对话框。 视图中的一个组件是时间选择器。 执行此操作时,计时器选择器的OK+Cancel按钮将控制,FragmentDialog默认按钮将禁用 这会导致一个问题,因为根据用户数据,我会显示/隐藏时间选择器视图,当它被隐藏时,它也会隐藏OK+Cancel按钮 拥有自定义视图非常重要,这样用户就可以在单个视图中选择所有相关数据 编辑-添加显示问题的图像 layout.xml <ScrollView xmlns:android="http://schemas.an
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="1000dp"
android:paddingLeft="5dp"
android:paddingRight="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<TextView
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="50"
android:text="@string/automatic_backup_type"
android:textColor="@color/dialog_text_color"/>
<!-- depending on the selected value here the timePart layout is showed or hide -->
<Spinner
android:id="@+id/automaticBackupType"
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="50"
android:background="@drawable/dialog_spinner_background"
android:prompt="@string/automatic_backup_type"
android:textColor="@color/dialog_text_color"
android:spinnerMode="dropdown"/>
</LinearLayout>
<!-- Some more controls here that are not relevant -->
<LinearLayout
android:id="@+id/timePart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/automatic_backup_time"
android:textColor="@color/dialog_text_color"/>
<TimePicker
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
自动备份配置ERT代码:
public static class AutomaticBackupConfigurationAlert extends DialogFragment {
private Spinner automaticBackupType;
private View timePart;
private TimePicker time;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AutomaticBackupType type;
Calendar time;
if (savedInstanceState != null) {
type = (AutomaticBackupType)savedInstanceState.getSerializable(KEY_TYPE);
time = (Calendar)savedInstanceState.getSerializable(KEY_TIME);
} else {
type = SettingsHelper.getAutomaticBackupType();
time = SettingsHelper.getAutomaticBackupTime();
}
LayoutInflater inflater = LayoutInflater.from(getActivity());
@SuppressLint("InflateParams")
View view = inflater.inflate(R.layout.dialog_automatic_backup, null);
this.automaticBackupType = view.findViewById(R.id.automaticBackupType);
this.timePart = view.findViewById(R.id.timePart); // When this is hide, no buttons for OK+Cancel
this.time = view.findViewById(R.id.time);
updateVisibility(type);
{
// backup type
ArrayAdapter<AutomaticBackupType> adapter = new ArrayAdapter<>(getActivity(), R.layout.dialog_spinner_item, AutomaticBackupType.values());
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
automaticBackupType.setAdapter(adapter);
automaticBackupType.setSelection(type.ordinal());
}
{
// time
this.time.setIs24HourView(DateFormat.is24HourFormat(getActivity()));
this.time.setCurrentHour(time.get(Calendar.HOUR_OF_DAY));
this.time.setCurrentMinute(time.get(Calendar.MINUTE));
}
automaticBackupType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
AutomaticBackupType tmpAutomaticBackupType = (AutomaticBackupType)automaticBackupType.getSelectedItem();
updateVisibility(tmpAutomaticBackupType);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.automatic_backup_configuration_title)
.setView(view)
.setPositiveButton(R.string.btn_save, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// Do nothing here because we override this button later to change the close behaviour.
// However, we still need this because on older versions of Android unless we
// pass a handler the button doesn't get instantiated
}
})
.setNegativeButton(R.string.btn_cancel, null)
.create();
}
@Override
public void onStart() {
super.onStart();
AlertDialog d = (AlertDialog)getDialog();
if (d != null) {
Button positiveButton = d.getButton(Dialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(v -> {
// save the data
});
}
}
private void updateVisibility(AutomaticBackupType tmpAutomaticBackupType) {
if (tmpAutomaticBackupType != null) {
UiHelper.setVisibility(timePart, !tmpAutomaticBackupType.equals(AutomaticBackupType.disabled), true);
}
}
}
公共静态类AutomaticBackupConfigurationERT扩展DialogFragment{
私有微调器自动备份类型;
私有视图时间部分;
私人时间选择器时间;
@非空
@凌驾
创建对话框上的公共对话框(Bundle savedInstanceState){
自动备份类型;
日历时间;
如果(savedInstanceState!=null){
type=(AutomaticBackupType)savedInstanceState.getSerializable(键类型);
时间=(日历)savedInstanceState.getSerializable(键时间);
}否则{
type=SettingsHelper.getAutomaticBackupType();
时间=设置Shelper.getAutomaticBackupTime();
}
LayoutInflater充气器=LayoutInflater.from(getActivity());
@SuppressLint(“充气参数”)
视图=充气机。充气(R.layout.dialog\u automatic\u backup,null);
this.automaticBackupType=view.findViewById(R.id.automaticBackupType);
this.timePart=view.findviewbyd(R.id.timePart);//此选项处于隐藏状态时,没有“确定+取消”按钮
this.time=view.findViewById(R.id.time);
可更新性(类型);
{
//备份类型
ArrayAdapter=新的ArrayAdapter(getActivity(),R.layout.dialog_spinner_项,AutomaticBackupType.values());
adapter.setDropDownViewResource(R.layout.spinner\u下拉项);
automaticBackupType.setAdapter(适配器);
automaticBackupType.setSelection(type.ordinal());
}
{
//时间
this.time.setIs24HourView(DateFormat.is24HourFormat(getActivity());
this.time.setCurrentHour(time.get(Calendar.HOUR OF_DAY));
this.time.setCurrentMinute(time.get(Calendar.MINUTE));
}
automaticBackupType.setOnItemSelectedListener(新的AdapterView.OnItemSelectedListener(){
@凌驾
已选择公共视图(AdapterView父视图、视图视图、整型位置、长id){
AutomaticBackupType tmpAutomaticBackupType=(AutomaticBackupType)AutomaticBackupType.getSelectedItem();
可更新性(tmpAutomaticBackupType);
}
@凌驾
未选择公共无效(AdapterView父级){
}
});
返回新的AlertDialog.Builder(getActivity())
.setTitle(R.string.automatic\u backup\u configuration\u title)
.setView(视图)
.setPositiveButton(R.string.btn_保存,新建DialogInterface.OnClickListener(){
@凌驾
public void onClick(DialogInterface dialog,int which){
//此处不执行任何操作,因为我们稍后会覆盖此按钮以更改关闭行为。
//然而,我们仍然需要它,因为在旧版本的Android上,除非我们
//传递一个处理程序,使按钮不会被实例化
}
})
.setNegativeButton(R.string.btn_取消,空)
.create();
}
@凌驾
public void onStart(){
super.onStart();
AlertDialog d=(AlertDialog)getDialog();
如果(d!=null){
按钮正按钮=d.getButton(对话框按钮正);
positiveButton.setOnClickListener(v->{
//保存数据
});
}
}
私有void可更新性(AutomaticBackupType tmpAutomaticBackupType){
if(tmpAutomaticBackupType!=null){
setVisibility(timePart,!tmpAutomaticBackupType.equals(AutomaticBackupType.disabled),true);
}
}
}
刚刚找到了一个解决方案(我不喜欢它,但它很有效)
我把它贴在这里,以防别人需要它
时间选择器似乎具有与AlertDialog相同id的正/自然/负按钮。当我使用对话框生成器设置它们时,它实际上在时间选择器中设置了一个
通常,解决方案是将视图添加到对话框中,而不使用时间选择器视图,并且仅在设置按钮后添加该视图
上述代码在两个位置发生了更改:
时间设置块中的onCreateDialog方法中的第一个:
{
// time
this.time.setIs24HourView(DateFormat.is24HourFormat(getActivity()));
this.time.setCurrentHour(time.get(Calendar.HOUR_OF_DAY));
this.time.setCurrentMinute(time.get(Calendar.MINUTE));
timePart.removeView(this.time); // remove the TimePicker view from the layout
}
onStart方法中的第二个
public void onStart() {
super.onStart();
AlertDialog d = (AlertDialog)getDialog();
if (d != null) {
Button positiveButton = d.getButton(Dialog.BUTTON_POSITIVE);
timePart.addView(time); // Now we can add the view
positiveButton.setOnClickListener(v -> {
// save the data
});
}
}
刚刚找到了一个解决方案(我不喜欢它,但它很有效)
我把它贴在这里,以防别人需要它
时间选择器似乎具有与AlertDialog相同id的正/自然/负按钮。当我使用对话框生成器设置它们时,它实际上在时间选择器中设置了一个
通常,解决方案是将视图添加到对话框中,而不使用时间选择器视图,并且仅在设置按钮后添加该视图
上述代码在两个位置发生了更改:
时间设置块中的onCreateDialog方法中的第一个:
{
// time
this.time.setIs24HourView(DateFormat.is24HourFormat(getActivity()));
this.time.setCurrentHour(time.get(Calendar.HOUR_OF_DAY));
this.time.setCurrentMinute(time.get(Calendar.MINUTE));
timePart.removeView(this.time); // remove the TimePicker view from the layout
}
onStart方法中的第二个
public void onStart() {
super.onStart();
AlertDialog d = (AlertDialog)getDialog();
if (d != null) {
Button positiveButton = d.getButton(Dialog.BUTTON_POSITIVE);
timePart.addView(time); // Now we can add the view
positiveButton.setOnClickListener(v -> {
// save the data
});
}
}
不清楚您面临的问题是什么。问题是,如果用户选择禁用自动备份,我将隐藏计时器组件。当我这样做时,对话框的“确定”和“取消”按钮消失,我无法确认或取消更改。如果我在视图布局中不使用时间选择器,就不会有问题