Intereting Posts
Поток ресурсов Google Play остается пустым Как обнаружить левый и правый наклон устройства Android, установленного с помощью акселерометра? К сожалению, MyApp остановился. Как я могу это решить? ОтправитьВопросы в BroadcastReceiver EditText не заполнит оставшееся пространство Android API Google Drive «соединение не выполнено» Невозможно подключиться к виртуальной машине В Android, почему все классы org.apache.http. * Устарели в API 22 (и что я должен использовать в качестве замены)? Пользовательский шрифт в android ListView Возможно ли анимировать диалоговое окно «Диалог»? Совместите значок с помощью значка на панели инструментов – Android Material Design Получите MSISDN с SIM-карты с помощью Android Файл не синхронизирован. Использование 1.7 требует компиляции с Android 4.4 (KitKat); В настоящее время использует API 16 TextView Marquee не работает Как я могу раздавать бесплатные просмотренные копии моего платного приложения для Android?

Кнопка Android TimePicker AM / PM не вызывает onTimeChanged

У меня возникли некоторые проблемы с внедрением TimePicker в моем приложении, которое позволяет пользователю изменять время записи базы данных до ее вставки.

Проблема в том, что при нажатии кнопки AM / PM метод onTimeChanged (View, int, int) не вызывается. Однако, когда я изменяю либо часовое, либо минутное значение TimePicker, вызывается onTimeChanged ().

Сценарии:

  • Пользователь просто нажимает кнопку AM / PM: AM / PM не обновляется
  • Пользователь нажимает часы / минуты: время обновляется
  • Пользователь нажимает кнопку AM / PM, а затем меняет часы / минуты: время и AM / PM обновляются

Я ошибаюсь, думая, что кнопка AM / PM должна быть нажата, чтобы обновить время, не изменяя значение времени после кнопки am / pm?

Я собрал небольшой тестовый проект, чтобы воспроизвести это, и вот код:

Мероприятия

public class TestActivity extends Activity implements OnTimeChangedListener { private Calendar mCalendar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.timepicker); mCalendar = Calendar.getInstance(); TimePicker tp = (TimePicker)findViewById(R.id.timepicker); tp.setIs24HourView(false); tp.setOnTimeChangedListener(this); } @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { Log.d("TAG", "In onTimeChanged"); mCalendar.set(mCalendar.get(Calendar.YEAR), mCalendar.get(Calendar.MONTH), mCalendar.get(Calendar.DAY_OF_MONTH), hourOfDay, minute); setCalendarTime(); } private void setCalendarTime() { Date date = mCalendar.getTime(); if (date != null) { SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yy '@' h:mm a"); String dateTime = formatter.format(date); Toast.makeText(this, dateTime, Toast.LENGTH_LONG).show(); } } } 

timepicker.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true"> <TimePicker android:id="@+id/timepicker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="5dip" android:layout_marginRight="5dip"/> </LinearLayout> 

Solutions Collecting From Web of "Кнопка Android TimePicker AM / PM не вызывает onTimeChanged"

Я проверил код. Да, вы правы, кнопка TimePicker AM / PM не вызывает метод onTimeChanged, который должен.

На самом деле, это ошибка. Об этом сообщается в google. Вы можете найти это здесь
http://code.google.com/p/android/issues/detail?id=18982

Пожалуйста, проголосуйте, комментируйте & опубликуйте отчет об ошибке, чтобы повысить его приоритет и как можно скорее установить его командой разработчиков.

Я нашел этот ответ, но для меня это не сработало, поэтому я решил обновить его.

В 3.2 (и выше?), Выбор времени не имеет кнопки для am / pm. Вместо этого он имеет NumberPicker. Следующий код работал для меня. Последний бит существует, потому что мне нужно ограничить время, выбранное не раньше, чем «мин» и не больше, чем «max», поэтому мне пришлось проверять дату, выбранную в соответствующем элементе управления DatePicker:

  NumberPicker amPmView = (NumberPicker)((ViewGroup)tp.getChildAt(0)).getChildAt(3); amPmView.setOnValueChangedListener(new OnValueChangeListener() { @Override public void onValueChange(NumberPicker arg0, int arg1, int arg2) { if(arg0.getValue()== 1){ if (tp.getCurrentHour() < 12) tp.setCurrentHour(tp.getCurrentHour() + 12); } else{ if (tp.getCurrentHour() >= 12) tp.setCurrentHour(tp.getCurrentHour() - 12); } int year = dp.getYear(); int month = dp.getMonth(); int dayOfMonth = dp.getDayOfMonth(); int hourOfDay = tp.getCurrentHour(); int minute = tp.getCurrentMinute(); if (year == min.get(Calendar.YEAR) && month == min.get(Calendar.MONTH) && dayOfMonth == min.get(Calendar.DAY_OF_MONTH)){ if ((hourOfDay < min.get(Calendar.HOUR_OF_DAY))|| (hourOfDay == min.get(Calendar.HOUR_OF_DAY) && (minute < min.get(Calendar.MINUTE)))){ tp.setCurrentHour(min.get(Calendar.HOUR_OF_DAY)); tp.setCurrentMinute(min.get(Calendar.MINUTE)); } }else if (year == max.get(Calendar.YEAR) && month == max.get(Calendar.MONTH) && dayOfMonth == max.get(Calendar.DAY_OF_MONTH)){ if ((hourOfDay > max.get(Calendar.HOUR_OF_DAY))|| (hourOfDay == max.get(Calendar.HOUR_OF_DAY) && (minute > max.get(Calendar.MINUTE)))){ tp.setCurrentHour(max.get(Calendar.HOUR_OF_DAY)); tp.setCurrentMinute(max.get(Calendar.MINUTE)); } } } }); 

Решение Velval – единственное решение, которое работает и совместимо с различными версиями Android. Я попробовал это на api 17 и 23. но у него есть проблема, которая мешает оригинальному прослушиванию кликов на Android 6. так вот что со мной работало. Использовать touch вместо щелчка:

 public class MyTimePicker extends TimePicker { private OnTimeChangedListener onTimeChangedListener; public MyTimePicker(Context context) { super(context); // init(); } public MyTimePicker(Context context, AttributeSet attrs) { super(context, attrs); //init(); } public MyTimePicker(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // init(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public MyTimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // Stop ScrollView from getting involved once you interact with the View if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { ViewParent p = getParent(); if (p != null) p.requestDisallowInterceptTouchEvent(true); } return false; } @Override public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) { super.setOnTimeChangedListener(onTimeChangedListener); this.onTimeChangedListener = onTimeChangedListener; } @Override protected void onFinishInflate() { super.onFinishInflate(); init(); } private void init() { try { ViewGroup amPmView; ViewGroup v1 = (ViewGroup) getChildAt(0); ViewGroup v2 = (ViewGroup) v1.getChildAt(0); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { ViewGroup v3 = (ViewGroup) v2.getChildAt(0); amPmView = (ViewGroup) v3.getChildAt(3); } else { amPmView = (ViewGroup) v2.getChildAt(3); } View.OnTouchListener listener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { onTimeChangedListener.onTimeChanged(MyTimePicker.this, getCurrentHour(), getCurrentMinute()); } else { int hour = getCurrentHour(); if (hour >= 12) { hour -= 12; } else { hour += 12; } onTimeChangedListener.onTimeChanged(MyTimePicker.this, hour, getCurrentMinute()); } return false; } }; View am = amPmView.getChildAt(0); View pm = amPmView.getChildAt(1); am.setOnTouchListener(listener); pm.setOnTouchListener(listener); } catch (Exception e) { // DO nothing... just ignore the workaround if this fails. } } } 

Пожалуйста, используйте приведенный ниже код, он отлично работает для меня.

 final TimePicker tp=(TimePicker)findViewById(R.id.timePicker1); View amPmView = ((ViewGroup)tp.getChildAt(0)).getChildAt(2); if(amPmView instanceof Button) { amPmView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.d("OnClickListener", "OnClickListener called"); if(v instanceof Button) { if(((Button) v).getText().equals("AM")) { ((Button) v).setText("PM"); if (tp.getCurrentHour() < 12) { tp.setCurrentHour(tp.getCurrentHour() + 12); } } else{ ((Button) v).setText("AM"); if (tp.getCurrentHour() >= 12) { tp.setCurrentHour(tp.getCurrentHour() - 12); } } } } }); } 

Эта ссылка показывает, что onTimeChanged(); Вызывает вызов, который запускает диспетчер событий.

Если вы не получаете нужные вам события (даже если они, кажется, посылают), вам придется

  • Расширение по умолчанию TimerPicker,

  • Override mAmPmButton.setOnClickListener,

  • И включить вашу версию в представление.


 mAmPmButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { requestFocus(); if (mIsAm) { // Currently AM switching to PM if (mCurrentHour < 12) { mCurrentHour += 12; } } else { // Currently PM switching to AM if (mCurrentHour >= 12) { mCurrentHour -= 12; } } mIsAm = !mIsAm; mAmPmButton.setText(mIsAm ? mAmText : mPmText); onTimeChanged(); } }); 

Имел ту же проблему при создании TimePicker в коде, и ни один из предоставленных решений не работал для меня. Ниже было то, что я делал. Протестировано на уровнях API 18, 21 и 23

 final TimePicker tp = new TimePicker(getContext()); tp.setOnTimeChangedListener(this); try { ViewGroup amPmView; ViewGroup v1 = (ViewGroup)tp.getChildAt(0); ViewGroup v2 = (ViewGroup)v1.getChildAt(0); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { ViewGroup v3 = (ViewGroup)v2.getChildAt(0); amPmView = (ViewGroup)v3.getChildAt(3); } else { amPmView = (ViewGroup)v2.getChildAt(3); } View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { tp.setCurrentHour((tp.getCurrentHour() + 12) % 24); } }; View am = amPmView.getChildAt(0); View pm = amPmView.getChildAt(1); am.setOnClickListener(listener); pm.setOnClickListener(listener); } catch (Exception e) { // DO nothing... just ignore the workaround if this fails. } 

Вот быстрый проект, который я объединил, поддерживающий Android 4.0+. В основном, он показывает TextView, который всегда синхронизируется с TimePicker, независимо от того, какой вертикальный счетчик манипулирует пользователем.

https://gist.github.com/danialgoodwin/5694256

Я делаю этот метод true, если TimePicker выбирает AM и false, если TimePicker выбирает PM. Note: suppresLint для Api 8 не работает .getvalue () statement

Saludos !! 🙂

 @SuppressLint("NewApi") private boolean isAM(TimePicker timePicker){ NumberPicker numberPickerAmPm = (NumberPicker)((ViewGroup) timePicker.getChildAt(0)).getChildAt(3); if(numberPickerAmPm.getValue()==0){ //sendToast("es am"); return true; }else{ //sendToast("es pm"); return false; } } 

Я хотел бы поделиться своим решением, так как другие обходные пути, опубликованные здесь, не работают для меня. Но я могу понять это. Эта строка:

  View amPmView = ((ViewGroup)tp.getChildAt(0)).getChildAt(2); 

Кажется, не возвращает колесо выбора для AM_PM.

  NumberPicker amPmView = (NumberPicker ((ViewGroup)tp.getChildAt(0)).getChildAt(3); 

Ни то, ни другое, так как это возвращает TextView . Кажется, это ярлык, обозначенный на сборщике.

Но, используя последний, получение четвертого дочернего элемента возвращает мне колесо выбора для AM_PM. Вот что я получил до сих пор:

  NumberPicker amPmView = (NumberPicker)((ViewGroup) mTimePicker.getChildAt(0)).getChildAt(4); amPmView.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { Log.i(NoteApplication.TAG, "AM_PM selected..."); } }); 

Теперь я могу обнаружить изменения в AM_PM. Я надеюсь, что это поможет другим людям, которые не могут получить его через getChildAt(2) или getChildAt(3) как описано другими ответами.

Также обратите внимание, что это относится к классу TimePicker , я еще не пробовал это на TimePickerDialog поэтому я не уверен в этом. Я тестирую на min sdk 8, нацеливая api 22.

НТН

Я также столкнулся с такой же проблемой, используя API 21, и проблема еще не решена.

Я заменил представление TimePicker на TimePickerDialog, и он сработал.

Следующий код устанавливает TextView с временем, выбранным из TimePickerDialog. Вы можете заменить tv.setText () любой логикой:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final TextView tv = (TextView)findViewById(R.id.textView); Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() { @Override public void onTimeSet(TimePicker view, int hourOfDay, int minute) { tv.setText(String.format(Locale.getDefault(),"Hour: %d, Minute: %d ",hourOfDay,minute)); } }, hour, minute, true); timePickerDialog.show(); } 

При использовании API 25 Nougat код Velval / Hisham является единственным, который работает, но не в ландшафтном режиме. Я изменил код, и он отлично работает :):

 public class AMPMTimePicker extends TimePicker { private static final String TAG = "AMPMTimePicker"; private OnTimeChangedListener onTimeChangedListener; public AMPMTimePicker(Context context) { super(context); } public AMPMTimePicker(Context context, AttributeSet attrs) { super(context, attrs); } public AMPMTimePicker(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public AMPMTimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // Stop ScrollView from getting involved once you interact with the View if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { ViewParent p = getParent(); if (p != null) p.requestDisallowInterceptTouchEvent(true); } return false; } @Override public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) { super.setOnTimeChangedListener(onTimeChangedListener); this.onTimeChangedListener = onTimeChangedListener; } @Override protected void onFinishInflate() { super.onFinishInflate(); init(); } @SuppressWarnings("deprecation") private void init() { try { ViewGroup amPmView; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // LinearLayout (LOLLIPOP) // GridLayout (M-LANDSCAPE) // LinearLayout (M-PORTRAIT) ViewGroup v1 = (ViewGroup) getChildAt(0); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // FrameLayout (LOLLIPOP-LANDSCAPE) // FrameLayout - id:time_header (LOLLIPOP-PORTRAIT) ViewGroup v2 = (ViewGroup) v1.getChildAt(0); // FrameLayout - id:TimeHeader (LOLLIPOP-LANDSCAPE) // LinearLayout (LOLLIPOP-PORTRAIT) ViewGroup v3 = (ViewGroup) v2.getChildAt(0); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { ViewGroup v4 = (ViewGroup) v3.getChildAt(0); // LinearLayout (LOLLIPOP) amPmView = (ViewGroup) v4.getChildAt(3); // LinearLayout - id:ampm_layout (LOLLIPOP) } else { // PORTRAIT amPmView = (ViewGroup) v3.getChildAt(3); // LinearLayout - id:ampm_layout (LOLLIPOP) } } else { // M and after if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { ViewGroup v2 = (ViewGroup) v1.getChildAt(1); // RelativeLayout (M) amPmView = (ViewGroup) v2.getChildAt(1); // LinearLayout - id:ampm_layout (M) } else { ViewGroup v2 = (ViewGroup) v1.getChildAt(0); // RelativeLayout - id:time_header (M) amPmView = (ViewGroup) v2.getChildAt(3); // LinearLayout - id:ampm_layout (M) } } View am = amPmView.getChildAt(0); // AppCompatCheckedTextView - id:am_label View pm = amPmView.getChildAt(1); // AppCompatCheckedTextView - id:pm_label View.OnTouchListener listener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int hour; int minute; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { hour = getCurrentHour(); minute = getCurrentMinute(); } else { hour = getHour(); minute = getMinute(); } hour = (hour >= 12) ? hour - 12 : hour + 12; onTimeChangedListener.onTimeChanged(AMPMTimePicker.this, hour, minute); return false; } }; am.setOnTouchListener(listener); pm.setOnTouchListener(listener); } } catch (Exception e) { Log.e(TAG, "TimePicker is not defined for this Android version : " + e.getMessage()); } } }