You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Widget中使用onSavedInstanceState?屏幕旋转后按钮日期丢失求助

解决屏幕旋转时Button日期丢失与文本为空的问题

Hey there! Let's break down and fix the two issues you're encountering: the empty Button text and lost selected date after screen rotation.

1. 为什么按钮文本始终为空?

大概率是你的setDate方法里没有将选中的日期格式化后设置给startDate Button。当你选择完日期后,需要把Date对象转换成用户友好的字符串(比如"yyyy-MM-dd"格式),然后调用startDate.setText(formattedDate)。

举个完整的setDate方法示例:

private void setDate(final Button dateButton) {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR);
    int month = calendar.get(Calendar.MONTH);
    int day = calendar.get(Calendar.DAY_OF_MONTH);

    DatePickerDialog datePickerDialog = new DatePickerDialog(
            this,
            new DatePickerDialog.OnDateSetListener() {
                @Override
                public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {
                    // 格式化选中的日期为字符串
                    String formattedDate = selectedYear + "-" + (selectedMonth + 1) + "-" + selectedDay;
                    // 设置给Button
                    dateButton.setText(formattedDate);
                    // 保存选中的日期,方便旋转后恢复
                    mSelectedStartDate = formattedDate;
                }
            },
            year, month, day);
    datePickerDialog.show();
}

2. 为什么旋转屏幕后已选日期丢失?

Android在屏幕旋转时会销毁并重建Activity,所有未保存的临时状态都会丢失。解决这个问题有两种常用方案:

方案一:使用ViewModel(推荐,更稳定)

ViewModel专门用于在配置变化(比如旋转)时保存UI相关数据,不会随Activity销毁而消失。

首先,创建一个ViewModel类:

import androidx.lifecycle.ViewModel;

public class DateViewModel extends ViewModel {
    private String selectedStartDate;

    public String getSelectedStartDate() {
        return selectedStartDate;
    }

    public void setSelectedStartDate(String selectedStartDate) {
        this.selectedStartDate = selectedStartDate;
    }
}

然后在你的Activity中使用它:

import androidx.lifecycle.ViewModelProvider;

public class YourActivity extends AppCompatActivity {
    private Button startDate;
    private DateViewModel mDateViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);

        // 初始化ViewModel
        mDateViewModel = new ViewModelProvider(this).get(DateViewModel.class);

        startDate = findViewById(R.id.startDate);
        // 恢复之前保存的日期
        if (mDateViewModel.getSelectedStartDate() != null) {
            startDate.setText(mDateViewModel.getSelectedStartDate());
        }

        startDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setDate(startDate);
            }
        });
    }

    private void setDate(final Button dateButton) {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        DatePickerDialog datePickerDialog = new DatePickerDialog(
                this,
                new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {
                        String formattedDate = selectedYear + "-" + (selectedMonth + 1) + "-" + selectedDay;
                        dateButton.setText(formattedDate);
                        // 保存到ViewModel
                        mDateViewModel.setSelectedStartDate(formattedDate);
                    }
                },
                year, month, day);
        datePickerDialog.show();
    }
}

方案二:重写onSaveInstanceState和onRestoreInstanceState

通过Activity的实例状态Bundle来保存和恢复数据:

public class YourActivity extends AppCompatActivity {
    private Button startDate;
    private static final String KEY_START_DATE = "start_date";
    private String mSelectedStartDate;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);

        startDate = findViewById(R.id.startDate);

        // 恢复状态
        if (savedInstanceState != null) {
            mSelectedStartDate = savedInstanceState.getString(KEY_START_DATE);
            if (mSelectedStartDate != null) {
                startDate.setText(mSelectedStartDate);
            }
        }

        startDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                setDate(startDate);
            }
        });
    }

    // 保存状态
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(KEY_START_DATE, mSelectedStartDate);
    }

    // 可选:也可以用onRestoreInstanceState恢复
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mSelectedStartDate = savedInstanceState.getString(KEY_START_DATE);
        if (mSelectedStartDate != null) {
            startDate.setText(mSelectedStartDate);
        }
    }

    private void setDate(final Button dateButton) {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        DatePickerDialog datePickerDialog = new DatePickerDialog(
                this,
                new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {
                        mSelectedStartDate = selectedYear + "-" + (selectedMonth + 1) + "-" + selectedDay;
                        dateButton.setText(mSelectedStartDate);
                    }
                },
                year, month, day);
        datePickerDialog.show();
    }
}

总结

  • 按钮文本为空:确保在onDateSet回调中把格式化后的日期设置给Button。
  • 旋转后日期丢失:用ViewModel(推荐)或者保存实例状态的方式来持久化选中的日期。

内容的提问来源于stack exchange,提问作者SpiderKing88

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:58:32