6

表示するために TextView に設定された時間を設定する TimePickerDialog があります。ここで、TimePicker (TimePickerDialog 内) の分間隔を 15 分に設定するための助けが必要です。TimePicker に関連する 15 分間隔の問題が投稿されているのを見たことがありますが、TimePickerDialog 内で作成される TimePicker の使用方法がわからないため、TimePickerDialog に適用する方法がわかりません。私はAndroidが初めてで、この問題で完全に迷っています。前もって感謝します。

4

4 に答える 4

15

@Rizwan のthisこの他のスレッドの組み合わせを使用して、 TimePickerDialog. 主な問題は、ほとんどの機能が AndroidTimePickerDialogTimePickerクラスによって隠され、許可されていないように見えることです。

  1. TimePickerDialog簡単にアクセスできるように拡張する
  2. リフレクションを使用してディスプレイ内に到達し、必要なビットにアクセスします (以下を参照)。
  3. 分「NumberPicker」を再配線して、値を表示します
  4. を再配線して、カスタムインクリメントを尊重するTimePickerフォームから値を受け取り、返します。NumberPicker
  5. onStop()をブロックして、閉じるときに値がリセットされないようにします。

警告

UI 内に到達する際の主な問題は、変更される可能性のある ID によって要素が参照され、ID の名前でさえも永久に同じであるとは保証されないことです。そうは言っても、これは機能し、安定したソリューションであり、近い将来に機能する可能性があります. 私の意見では、空の catch ブロックは、UI が変更されたことを警告し、デフォルト (1 分刻み) の動作にフォールバックする必要があります。

解決

    private class DurationTimePickDialog extends TimePickerDialog
    {
        final OnTimeSetListener mCallback;
        TimePicker mTimePicker;
        final int increment;

        public DurationTimePickDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView, int increment)
        {
            super(context, callBack, hourOfDay, minute/increment, is24HourView);
            this.mCallback = callBack;
            this.increment = increment;
        }

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

        @Override
        protected void onStop()
        {
            // override and do nothing
        }

        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            try
            {
                Class<?> rClass = Class.forName("com.android.internal.R$id");
                Field timePicker = rClass.getField("timePicker");
                this.mTimePicker = (TimePicker)findViewById(timePicker.getInt(null));
                Field m = rClass.getField("minute");
                
                NumberPicker mMinuteSpinner = (NumberPicker)mTimePicker.findViewById(m.getInt(null));
                mMinuteSpinner.setMinValue(0);
                mMinuteSpinner.setMaxValue((60/increment)-1);
                List<String> displayedValues = new ArrayList<String>();
                for(int i=0;i<60;i+=increment)
                {
                    displayedValues.add(String.format("%02d", i));
                }
                mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

}

コンストラクターはインクリメント値を受け入れ、他のいくつかの参照を保持します。これはエラーチェックを省略していることに注意してください。60%increment==0

onCreateは、UI フィールドの名前とリフレクションを使用して現在の場所を検出します。ここでもエラーチェックが省略され、「フェイルセーフ」である必要があります。つまり、何か問題が発生した場合はデフォルトの動作に戻ります。

onClickがオーバーライドされ、正しい分の値がコールバック リスナーに返されます。

ダイアログが閉じたときに (正しくない) インデックス値が 2 回返されるのを防ぐために、onStop がオーバーライドされました。さあ、自分で試してみてください。

これのほとんどは、TimePickerDialog ソースを掘り下げた結果です。

Android 11+ のアップデート

上記の例で使用されているリフレクションは、graylist-max-qとしてマークされていました。つまり、Android 10 (API 29 - Q) 以降では使用できなくなります。短期間 ( 2021 年 8 月まで) は、Android 11 (API 30 - R) に対してビルドしながらターゲット バージョンを API 29 に戻すことができますが、この日以降、Play ストアはこれらのビルドを受け入れなくなり、API が必要になります。ビルド ターゲットとして 30。この最終的な障害は予期されており、上記の警告に記載されています。

于 2013-11-14T05:18:56.317 に答える
12

time-picker-dialog の代わりに time-picker を使用した場合は問題ありません。しかし、実際にはこれに対する解決策があります..これは私が同じ要件を満たすために使用したものです..私はCustomTimePickerDialogを使用しました。コード内で TimePickerDialog のみが CustomTimePickerDialog に変更されます。

CustomTimePickerDialog timePickerDialog = new CustomTimePickerDialog(myActivity.this, timeSetListener, 
            Calendar.getInstance().get(Calendar.HOUR), 
            CustomTimePickerDialog.getRoundedMinute(Calendar.getInstance().get(Calendar.MINUTE) + CustomTimePickerDialog.TIME_PICKER_INTERVAL), 
            false
);
timePickerDialog.setTitle("2. Select Time");
timePickerDialog.show();

これが私の CustomTimePickerDialog クラスです...プロジェクトでこのクラスを使用し、TimePickerDialogをCustomTimePickerDialogに変更してください..

public class CustomTimePickerDialog extends TimePickerDialog{

    public static final int TIME_PICKER_INTERVAL=10;
    private boolean mIgnoreEvent=false;

    public CustomTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute,
        boolean is24HourView) {
    super(context, callBack, hourOfDay, minute, is24HourView);
    }
/*
 * (non-Javadoc)
 * @see android.app.TimePickerDialog#onTimeChanged(android.widget.TimePicker, int, int)
 * Implements Time Change Interval
 */
    @Override
    public void onTimeChanged(TimePicker timePicker, int hourOfDay, int minute) {
        super.onTimeChanged(timePicker, hourOfDay, minute);
        this.setTitle("2. Select Time");
        if (!mIgnoreEvent){
            minute = getRoundedMinute(minute);
            mIgnoreEvent=true;
            timePicker.setCurrentMinute(minute);
            mIgnoreEvent=false;
        }
    }

    public static int getRoundedMinute(int minute){
         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;
         }

        return minute;
    }
}

この CustomTimePickerDialog クラスを使用した後は、コードで TimePickerDialog の代わりに CustomTimePickerDialog を使用して、TimePickerDialog クラスのデフォルト関数にアクセス/オーバーライドするだけです。簡単に言えば、あなたの timeSetListener はこの後次のようになります...

private CustomTimePickerDialog.OnTimeSetListener timeSetListener = new CustomTimePickerDialog.OnTimeSetListener() {
    @Override
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {

    }
}// using CustomTimePickerDialog
于 2012-04-02T06:44:14.540 に答える
1

通常の AlertDialog を使用し、setView を使用してカスタム TimePicker ビューを含めることができます。

于 2011-10-10T13:40:56.147 に答える
1
/**
 * Set TimePicker interval by adding a custom minutes list
 * TIME_PICKER_INTERVAL = Enter your Minutes;
 * @param timePicker
 */
private void setTimePickerInterval(TimePicker timePicker) {
    try {
        int TIME_PICKER_INTERVAL = 10;
        NumberPicker minutePicker = (NumberPicker) timePicker.findViewById(Resources.getSystem().getIdentifier(
                "minute", "id", "android"));
        minutePicker.setMinValue(0);
        minutePicker.setMaxValue((60 / TIME_PICKER_INTERVAL) - 1);
        List<String> displayedValues = new ArrayList<String>();
        for (int i = 0; i < 60; i += TIME_PICKER_INTERVAL) {
            displayedValues.add(String.format("%02d", i));
        }
        minutePicker.setDisplayedValues(displayedValues.toArray(new String[0]));
    } catch (Exception e) {
        Log.e(TAG, "Exception: " + e);
    }
}
于 2017-10-13T12:01:40.577 に答える