55

私のアプリケーションは、時間を設定するために TimePickerDialog を表示します。timePickerDialog が 5 分間隔で分を表示するようにします。

これは、次のコードで正常に機能します。

private final int TIME_PICKER_INTERVAL=5;
private boolean mIgnoreEvent=false;
…
    public TimePickerDialogs(Context arg0, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
    super(arg0, callBack, hourOfDay, minute, is24HourView);

    formato=Statics.formato;
}

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
    //super.onTimeChanged(arg0, arg1, arg2);

    if (mIgnoreEvent)
        return;
    if (minute%TIME_PICKER_INTERVAL!=0){
        int minuteFloor=minute-(minute%TIME_PICKER_INTERVAL);
        minute=minuteFloor + (minute==minuteFloor+1 ? TIME_PICKER_INTERVAL : 0);
        if (minute==60)
            minute=0;
        mIgnoreEvent=true;
        view.setCurrentMinute(minute);
        mIgnoreEvent=false;
    }
}

5 分間隔で選択できるのは分だけですが、タイムピッカー ダイアログは次のようになります。

時間と分

次の図のように、分が 5 分の範囲をどのように示しているかわかりません。

時間と分 - 5

検索しましたが、解決策が見つかりません。

4

11 に答える 11

131

次のカスタムクラスを使用してCustomTimePickerDialog、問題を解決すると思います。

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.widget.NumberPicker;
import android.widget.TimePicker;

public class CustomTimePickerDialog extends TimePickerDialog {

    private final static int TIME_PICKER_INTERVAL = 5;
    private TimePicker mTimePicker;
    private final OnTimeSetListener mTimeSetListener;

    public CustomTimePickerDialog(Context context, OnTimeSetListener listener,
            int hourOfDay, int minute, boolean is24HourView) {
        super(context, TimePickerDialog.THEME_HOLO_LIGHT, null, hourOfDay,
                minute / TIME_PICKER_INTERVAL, is24HourView);
        mTimeSetListener = listener;
    }

    @Override
    public void updateTime(int hourOfDay, int minuteOfHour) {
        mTimePicker.setCurrentHour(hourOfDay);
        mTimePicker.setCurrentMinute(minuteOfHour / TIME_PICKER_INTERVAL);
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        switch (which) {
            case BUTTON_POSITIVE:
                if (mTimeSetListener != null) {
                    mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
                            mTimePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
                }
                break;
            case BUTTON_NEGATIVE:
                cancel();
                break;
        }
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field timePickerField = classForid.getField("timePicker");
            mTimePicker = (TimePicker) findViewById(timePickerField.getInt(null));
            Field field = classForid.getField("minute");

            NumberPicker minuteSpinner = (NumberPicker) mTimePicker
                .findViewById(field.getInt(null));
            minuteSpinner.setMinValue(0);
            minuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
                displayedValues.add(String.format("%02d", i));
            }
            minuteSpinner.setDisplayedValues(displayedValues
                    .toArray(new String[displayedValues.size()]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

これがデモンストレーションのスクリーンショットです。

ここに画像の説明を入力

于 2013-12-05T09:53:34.300 に答える
18

美しいスタイルのマテリアル タイムピッカーを作成するこの素晴らしいライブラリMaterialDateTimePickerがあります。

次のいずれかの方法を使用して、間隔を定義できます。

  • setSelectableTimes(Timepoint[] times) Timepoint の配列を渡すことができます。これらの値は、ピッカーでの唯一の有効な選択です。setMinTime(Timepoint time) および setMaxTime(Timepoint time) は、このリストをさらに削減します。

  • setTimeInterval(int hourInterval, int minuteInterval, int secondInterval) TimePickerDialog で選択可能な時間の間隔を設定します。これは、setSelectableTimes の便利なラッパーです。

于 2016-05-02T10:59:02.850 に答える
7

@ anddev84 が言ったように、独自のカスタマイズされた TimePickerDialog でそれを行うことができます。

ただし、見つけることができるソースコードを見てください。

  1. TimePickerDialog はフレーム レイアウトです。このファイルを参照してください。TimePickerが含まれているだけです
  2. TimePicker ウィジェットは単なる線形レイアウトです。このファイルを参照してください。分スピナーがNumberPickerであることがわかります
  3. NumberPickerのコードを参照すると、パブリック メソッド setDisplayedValues(String[] displayedValues) があることがわかります。

    /**
     * Sets the values to be displayed.
     *
     * @param displayedValues The displayed values.
     */
    public void setDisplayedValues(String[] displayedValues)
    

したがって、これらの情報を使用して、限られた時間を表示する独自のタイム ピッカー ダイアログを簡単にカスタマイズできると思います。

于 2013-12-02T04:25:14.963 に答える
2

1時間以上の30分のインターバルに苦労しました。@Leeさんのコメントが見れなかったらもっと苦労するかもしれません。したがって、30 分間隔でダイアログの完全なコードを投稿するだけです。

public class IntervalTimePickerDialog extends TimePickerDialog {
    private static final String TAG = "IntervalPickerDialog";

    private final static int TIME_PICKER_INTERVAL = 30;
    private TimePicker timePicker;
    private final OnTimeSetListener callback;

    private int lastHour = -1;
    private int lastMinute = -1;

    public IntervalTimePickerDialog(Context context, int themeId, OnTimeSetListener callBack,
                                    int hourOfDay, int minute, boolean is24HourView) {
        super(context, themeId, callBack, hourOfDay, minute / TIME_PICKER_INTERVAL,
                is24HourView);
        lastHour = hourOfDay;
        lastMinute = minute;
        this.callback = callBack;
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        if (callback != null && timePicker != null) {
            timePicker.clearFocus();
            callback.onTimeSet(timePicker, timePicker.getCurrentHour(),
                    timePicker.getCurrentMinute() * TIME_PICKER_INTERVAL);
        }
    }

    @Override
    protected void onStop() {
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        try {
            Class<?> classForid = Class.forName("com.android.internal.R$id");
            Field timePickerField = classForid.getField("timePicker");
            this.timePicker = (TimePicker) findViewById(timePickerField.getInt(null));
            Field field = classForid.getField("minute");

            NumberPicker mMinuteSpinner = (NumberPicker) timePicker.findViewById(field.getInt(null));
            mMinuteSpinner.setMinValue(0);
            mMinuteSpinner.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
            List<String> displayedValues = new ArrayList<>();
            for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
                displayedValues.add(String.format("%02d", i));
            }
            mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
        super.onTimeChanged(view, hourOfDay, minute);
        if (lastHour != hourOfDay && lastMinute != minute) {
            view.setCurrentHour(lastHour);
            lastMinute = minute;
        } else {
            lastHour = hourOfDay;
            lastMinute = minute;
        }
    }
于 2016-02-19T08:39:45.947 に答える
1

上記の優れた受け入れられた回答に追加しました。問題は、Android の少なくとも一部のバージョンでは、選択した時間を変更すると、ダイアログのタイトルが誤った時間値に置き換えられることです。問題のあるメソッドである updateTitle() をオーバーライドすることはできませんが、onTimeChanged() で呼び出しを傍受し、super を呼び出さないか、固定引数で呼び出すことができます。

setTitle() メソッドがゼロ以外の文字列 ID で呼び出されたかどうかを調べましたが、ブール値自体またはその他のゲッター/セッターを使用することもできます。

@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
{
    if (autoTitle)
    {
        // Super will call a private updateTitle() method, so lets make
        // sure it has the right minute value.
        super.onTimeChanged(view, hourOfDay, minute * TIME_PICKER_INTERVAL);
    }
    else
    {
        // do nothing
    }
}

@Override
public void setTitle(int id)
{
    super.setTitle(id);
    autoTitle = (id == 0);
}

...

private boolean autoTitle = true;
于 2016-02-17T02:43:45.140 に答える
1

のコードを見ると、ユーザーに表示される前にTimePickerDialogを直接変更する方法が提供されているようには見えずTimePicker、画像に表示されている「間違った分」が表示されます。TimePickerDialog.javaを参照してください。

Android のデザインに基づいて、独自の TimePickerDialog を作成することをお勧めします。最初は難しそうに聞こえるかもしれませんが、

  1. そうすれば、必要に応じて実装をカスタマイズできます。これTimePickerには、分に表示する値の初期化が含まれます (ここで説明したように)。
  2. Android TimePickerDialog.java 自体はわずか 160 行で、非常に扱いやすいものです。
于 2013-12-02T03:55:43.700 に答える
-1

Android 5以降で同じタイムピッカー(時計ではない)ダイアログを使用しない場合は、テーマを変更してください。コンストラクターで直接変更できます。

 public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView, int time_interval) {
        super(context, TimePickerDialog.THEME_HOLO_LIGHT, callBack, hourOfDay, minute / time_interval, is24HourView);
        this.TIME_PICKER_INTERVAL = time_interval;
        this.callback = callBack;
    }
于 2015-09-02T16:42:40.617 に答える