android 工作室 30 分钟间隔时间选择器(微调器)

android studio 30 min interval on time picker(spinner)

我正在使用时间选择器微调器。我想实施 30 分钟间隔。
我正在使用的代码输出这种效果,如下图所示。

代码如下:

picker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
    @Override
    public void onTimeChanged(TimePicker view, int hour, int min) {

        timeoutput.setText(String.format("%02dh%02d", hour, min));
    }
});

back.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(Schedule.this, choosewalk.class);
        startActivity(intent);
    }
});

@SuppressLint("DefaultLocale")
private void TimeInterval(TimePicker picker) {
    try {
        int Interval = 30;
        NumberPicker minute = (NumberPicker) picker.findViewById(Resources.getSystem().getIdentifier(
            "minute", "id", "android"));
        minute.setMinValue(0);
        minute.setMaxValue((60 / Interval) - 1);
        List<String> displayedValue = new ArrayList<String>();
        for (int i = 0; i < 60; i += Interval) {
            displayedValue.add(String.format("%02d", i));
        }
        minute.setDisplayedValues(displayedValue.toArray(new String[0]));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我知道有类似的问题,但对于这个具体问题,我很纠结。我知道该方法适用于 5、10、15 等间隔。它以 30 分钟的间隔更改代码,这是有问题的。

好的,这是你的问题。你想要一个带有 0030 的轮子,并且你希望能够无限滚动它,所以它从 30 滴答到 00 并增加小时每次都打轮,对吧?这基本上就是 TimePicker 默认情况下的工作方式。

问题是这样的,来自NumberPicker

Note: If the number of items, i.e. the range ( getMaxValue() - getMinValue()) is less than the number of items shown on the selector wheel, the selector wheel will not wrap.

the max - min thing 是一种非常尴尬的表达方式(项目数实际上是 that + 1)-但基本上,微调器一次在屏幕上显示 三个 个项目,并且您需要 三个以上 个项目(因此至少有一个关闭-screen) 包装工作。这就是为什么它适用于你的其他间隔(15 分钟给你四个项目,这样就结束了)

不幸的是,我认为您对此无能为力 - 缺少包装是 NumberPicker 中的硬编码行为。你可以通过四个项目来伪造它,00300030,但在内部它仍然是值 03,一个转动的轮子,不是两个。并且 TimePicker 使用这些值,与 minValuemaxValue 进行比较,以检查轮子何时包裹以及小时需要自动更改。

无法读取处理此问题的侦听器(在 TimePickerSpinnerDelegate 中),因此您不能将其包装在假装正在运行的侦听器中 0 1 0 1 代替。侦听器还引用了一堆内部私有变量和方法,因此您不能将其复制到您自己的代码中并进行调整。从外观上看,您必须重新实现整个小部件及其相关 类


如果适合您,您可以将两个 NumberPicker 放在一起并自己重新制作。您将失去诸如 AM/PM 功能之类的东西,可能还有可访问性,这取决于您是否关心。这基本上有效:

public class MainActivity extends AppCompatActivity implements NumberPicker.OnValueChangeListener {

    private NumberPicker mMinuteSpinner;
    private NumberPicker mHourSpinner;


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

        mMinuteSpinner = findViewById(R.id.minPicker);
        mHourSpinner = findViewById(R.id.hourPicker);
        
        mMinuteSpinner.setMinValue(0);
        mMinuteSpinner.setMaxValue(3);
        mMinuteSpinner.setDisplayedValues(new String[]{"00", "30", "00", "30"});
        mMinuteSpinner.setOnValueChangedListener(this);

        mHourSpinner.setMinValue(0);
        mHourSpinner.setMaxValue(23);
        String[] hours = new String[24];
        for (int i = 0; i < 24; i++) {
            hours[i] = Integer.toString(i + 1);
        }
        mHourSpinner.setDisplayedValues(hours);
    }

    @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
        boolean advanced = (newVal == 0 && oldVal == 3) || (newVal == 2 && oldVal == 1);
        boolean regressed = (newVal == 3 && oldVal == 0) || (newVal == 1 && oldVal == 2);
        if (advanced) {
            mHourSpinner.setValue(mHourSpinner.getValue() + 1);
        } else if (regressed) {
            mHourSpinner.setValue(mHourSpinner.getValue() - 1);
        }
    }

}

好久没碰Java了!可能有更好的方法来做到这一点。但是,是的,侦听器只是检查它是否在四项列表的两个翻转点之间传递(它从 3000 以一种方式滚动,反之亦然滚动另一种方式方法)。这基本上就是 TimePicker 的工作原理