2013-09-06 2 views
1

У меня есть код, который отображает «TimePicker». Он позволяет установить минимальное и максимальное значение при выборе часа с 1,15 до 11,30, а также позволяет установить интервал до 15 минут. в минутах. Код отлично работает на версии 4 Android, когда TimePicker работает на прокрутке и в версии Android 2.3 TimePicker, когда отображается с кнопками «плюс» и «минус», когда вы нажимаете одну из этих кнопок на Exeption. Скажите, что делать в коде для запуска в новых и старых версиях Android?TimePicker отлично работает на версии 4 android, но в ошибке версии 2.3. (Android)

вот код:

Класс 1. MainActivity

import android.app.Activity; 
import android.app.Dialog; 
import android.app.TimePickerDialog.OnTimeSetListener; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.TextView; 
import android.widget.TimePicker; 

public class PickerTimeDialogProsto extends Activity { 

    int DIALOG_TIME = 1; 
    int myHour = 1; 
    int myMinute = 15; 
    TextView tvTime; 

    /** Called when the activity is first created. */ 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_picker_time_dialog_prosto); 
     tvTime = (TextView) findViewById(R.id.tvTime); 
    } 

    public void onclick(View view) { 
     showDialog(DIALOG_TIME); 
       } 

    protected Dialog onCreateDialog(int id) { 
     if (id == DIALOG_TIME) { 

     RangeTimePickerDialog tpd = new RangeTimePickerDialog(this, myCallBack, myHour, myMinute, true); 

     tpd.setMin(1, 15); 
     tpd.setMax(11, 30); 

     return tpd; 
     } 
     return super.onCreateDialog(id); 
    } 

    OnTimeSetListener myCallBack = new OnTimeSetListener() { 
    public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 
     myHour = hourOfDay; 
     myMinute = minute; 
     tvTime.setText("Time is " + myHour + " hours " + myMinute + " minutes"); 
    } 
    }; 
} 

Класс 2

import java.lang.reflect.Field; 
import java.text.DateFormat; 
import java.util.Calendar; 

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

/** 
* A time dialog that allows setting a min and max time. 
* 
*/ 
public class RangeTimePickerDialog extends TimePickerDialog { 

    private int minHour = -1; 
    private int minMinute = -1; 

    private int maxHour = 25; 
    private int maxMinute = 25; 

    private int currentHour = 0; 
    private int currentMinute = 0; 

    private Calendar calendar = Calendar.getInstance(); 
    private DateFormat dateFormat; 

    public RangeTimePickerDialog(Context context, OnTimeSetListener callBack, 
      int hourOfDay, int minute, boolean is24HourView) { 
     super(context, callBack, hourOfDay, minute, is24HourView); 
     currentHour = hourOfDay; 
     currentMinute = minute; 
     dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT); 

     try { 
      Class<?> superclass = getClass().getSuperclass(); 
      Field mTimePickerField = superclass.getDeclaredField("mTimePicker"); 
      mTimePickerField.setAccessible(true); 
      TimePicker mTimePicker = (TimePicker) mTimePickerField.get(this); 
      mTimePicker.setOnTimeChangedListener(this); 
     } catch (NoSuchFieldException e) { 
     } catch (IllegalArgumentException e) { 
     } catch (IllegalAccessException e) { 
     } 
    } 

    public void setMin(int hour, int minute) { 
     minHour = hour; 
     minMinute = minute; 
    } 

    public void setMax(int hour, int minute) { 
     maxHour = hour; 
     maxMinute = minute; 
    } 

    @Override 
    public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { 

     boolean validTime = true; 
     if (hourOfDay < minHour || (hourOfDay == minHour && minute < minMinute)) { 
      validTime = false; 
     } 

     if (hourOfDay > maxHour || (hourOfDay == maxHour && minute > maxMinute)) { 
      validTime = false; 
     } 

     if (validTime) { 
      currentHour = hourOfDay; 
      currentMinute = minute; 
     } 

     updateTime(currentHour, currentMinute); 
     updateDialogTitle(view, currentHour, currentMinute); 
    } 

    private void updateDialogTitle(TimePicker timePicker, int hourOfDay, 
      int minute) { 
     calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); 
     calendar.set(Calendar.MINUTE, minute); 
     String title = dateFormat.format(calendar.getTime()); 
     setTitle(title); 
    } 
} 

Вот что дает LOG:

09-06 11:34:21.802: D/dalvikvm(1213): GC_EXTERNAL_ALLOC freed 104K, 48% free 2819K/5379K, external 2046K/2137K, paused 54ms 
09-06 11:34:24.981: I/dalvikvm(1213): threadid=1: stack overflow on call to Landroid/text/SpannableStringBuilder;.getChars:VIILI 
09-06 11:34:24.981: I/dalvikvm(1213): method requires 36+20+20=76 bytes, fp is 0x4214a334 (52 left) 
09-06 11:34:24.981: I/dalvikvm(1213): expanding stack end (0x4214a300 to 0x4214a000) 
09-06 11:34:24.991: I/dalvikvm(1213): Shrank stack (to 0x4214a300, curFrame is 0x4214cebc) 
09-06 11:34:24.991: D/AndroidRuntime(1213): Shutting down VM 
09-06 11:34:24.991: W/dalvikvm(1213): threadid=1: thread exiting with uncaught exception (group=0x40015560) 
09-06 11:34:25.111: E/AndroidRuntime(1213): FATAL EXCEPTION: main 
09-06 11:34:25.111: E/AndroidRuntime(1213): java.lang.StackOverflowError 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.TextUtils.getChars(TextUtils.java:69) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.method.ReplacementTransformationMethod$ReplacementCharSequence.getChars(ReplacementTransformationMethod.java:151) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.TextUtils.getChars(TextUtils.java:69) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.graphics.Paint.measureText(Paint.java:1068) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.Styled.drawUniformRun(Styled.java:146) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.Styled.drawDirectionalRun(Styled.java:298) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.Styled.measureText(Styled.java:430) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.Layout.measureText(Layout.java:1518) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.Layout.getHorizontal(Layout.java:564) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.Layout.getHorizontal(Layout.java:548) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.text.Layout.getPrimaryHorizontal(Layout.java:533) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TextView.getFocusedRect(TextView.java:4222) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.FocusFinder.findNextFocus(FocusFinder.java:72) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:476) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:478) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:478) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:478) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:478) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:478) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:478) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.ViewGroup.focusSearch(ViewGroup.java:478) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.View.focusSearch(View.java:3494) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TextView.onCreateInputConnection(TextView.java:4611) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:942) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.view.inputmethod.InputMethodManager.restartInput(InputMethodManager.java:897) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TextView.setText(TextView.java:2649) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TextView.setText(TextView.java:2598) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.EditText.setText(EditText.java:78) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TextView.setText(TextView.java:2573) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.NumberPicker.updateView(NumberPicker.java:356) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.NumberPicker.setCurrent(NumberPicker.java:292) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.updateHourDisplay(TimePicker.java:333) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.setCurrentHour(TimePicker.java:281) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.app.TimePickerDialog.updateTime(TimePickerDialog.java:135) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at com.example.pickerdialog.RangeTimePickerDialog.onTimeChanged(RangeTimePickerDialog.java:75) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.onTimeChanged(TimePicker.java:352) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.updateHourDisplay(TimePicker.java:336) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.setCurrentHour(TimePicker.java:281) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.app.TimePickerDialog.updateTime(TimePickerDialog.java:135) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at com.example.pickerdialog.RangeTimePickerDialog.onTimeChanged(RangeTimePickerDialog.java:75) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.onTimeChanged(TimePicker.java:352) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.updateHourDisplay(TimePicker.java:336) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.setCurrentHour(TimePicker.java:281) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.app.TimePickerDialog.updateTime(TimePickerDialog.java:135) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at com.example.pickerdialog.RangeTimePickerDialog.onTimeChanged(RangeTimePickerDialog.java:75) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.onTimeChanged(TimePicker.java:352) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.updateHourDisplay(TimePicker.java:336) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.setCurrentHour(TimePicker.java:281) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.app.TimePickerDialog.updateTime(TimePickerDialog.java:135) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at com.example.pickerdialog.RangeTimePickerDialog.onTimeChanged(RangeTimePickerDialog.java:75) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.onTimeChanged(TimePicker.java:352) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.updateHourDisplay(TimePicker.java:336) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.setCurrentHour(TimePicker.java:281) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.app.TimePickerDialog.updateTime(TimePickerDialog.java:135) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at com.example.pickerdialog.RangeTimePickerDialog.onTimeChanged(RangeTimePickerDialog.java:75) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.onTimeChanged(TimePicker.java:352) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.updateHourDisplay(TimePicker.java:336) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.widget.TimePicker.setCurrentHour(TimePicker.java:281) 
09-06 11:34:25.111: E/AndroidRuntime(1213):  at android.app.Ti 
09-06 11:34:29.132: I/Process(1213): Sending signal. PID: 1213 SIG: 9 

ответ

1

Вы зацикливание. Ваш onTimeChanged() звонит updateTime() на таймер, который, в свою очередь, приводит к другому вызову onTimeChanged().

Один из способов исправить это - добавить булевский флаг в свой класс, чтобы предотвратить рекурсивные вызовы updateTime(). Что-то вроде:

boolean mIsOnTimeChanged; 

@Override 
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { 
    if (!mIsOnTimeChanged) { 
    mIsOnTimeChanged = true; 

    // your regular onTimeChanged() here 

    mIsOnTimeChanged = false; 
    } 
}