this.afd.list('/shoppingItems/')
не возвращает асинхронный наблюдаемый, который должен работать с трубой async
. Он возвращает ссылку на список в базе данных реального времени. Вы должны использовать valueChanges()
, чтобы вернуть это.
В вашем провайдере верните наблюдаемый,
getShoppingItems() {
console.log("Shopping items"+this.afd.list('/shoppingItems/'))
return this.afd.list('/shoppingItems/').valueChanges();//here
}
Если вы просматриваете $key/$value
, Проверьте подробности обновления для angularfire2 v4 до 5 . Это связано с тем, что FirebaseList
устарел и AngularFireList
теперь возвращается из версии 5.
Вызов .valueChanges () возвращает Observable без каких-либо метаданных. Если вы уже сохраняете ключ как свойство, тогда вы в порядке. Однако, если вы полагаетесь на ключ $, тогда вам нужно использовать .snapshotChanges ()
blockquote>Вам нужно использовать
snapshotChanges()
getShoppingItems() { console.log("Shopping items"+this.afd.list('/shoppingItems/')) return this.afd.list('/shoppingItems/').snapshotChanges();//here }
Чтобы получить доступ к
$key
или$value
в html, используйтеitem.payload.key
иitem.payload.val()
Это расширение для ответов fiddlers. Как-то onTimeChangedListener не установлен TimePickerDialog в некоторых версиях Android:
Метод onTimeChanged никогда не вызывается! Лучшее решение для этой проблемы в настоящее время, возможно, для кодирования пользовательского TimePickerDialog с минимальной / максимальной логикой от скрипача.
Более уродливая работа - это. (Добавление слушателя с использованием отражений) Я также обновляю заголовок, чтобы показать текущее время.
package com.mysuger.android.dialogs;
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);
}
}
Вы можете использовать это как отправную точку.
Я расширил TimePickerDialog и добавил 2 метода setMin
и setMax
.
В методе onTimeChanged
я проверяю, что новое время действует в отношении минимальных / максимальных времен.
По-прежнему требуется некоторое полирование, хотя ...
public class BoundTimePickerDialog extends TimePickerDialog {
private int minHour = -1, minMinute = -1, maxHour = 100, maxMinute = 100;
private int currentHour, currentMinute;
public BoundTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
super(context, callBack, hourOfDay, minute, is24HourView);
}
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) {
super.onTimeChanged(view, hourOfDay, minute);
boolean validTime;
if(hourOfDay < minHour) {
validTime = false;
}
else if(hourOfDay == minHour) {
validTime = minute >= minMinute;
}
else if(hourOfDay == maxHour) {
validTime = minute <= maxMinute;
}
else {
validTime = true;
}
if(validTime) {
currentHour = hourOfDay;
currentMinute = minute;
}
else {
updateTime(currentHour, currentMinute);
}
}
}
Для lolipop и более высокой версии Android вы можете использовать этот модифицированный класс RangeTimePickerDialog
(от lolipop, Timepicker использует режим часов (дизайн материала) по умолчанию, чтобы старый пользовательский класс не работал. Мы можем изменить режим для вращения для последней версии и может повторно использовать класс)
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, int dialogTheme, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView) {
super(context, callBack, hourOfDay, minute, is24HourView);
currentHour = hourOfDay;
currentMinute = minute;
dateFormat = DateFormat.getTimeInstance(DateFormat.SHORT);
fixSpinner(context, hourOfDay, minute, is24HourView);
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);
}
private void fixSpinner(Context context, int hourOfDay, int minute, boolean is24HourView) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // android:timePickerMode spinner and clock began in Lollipop
try {
// Get the theme's android:timePickerMode
//two modes are available clock mode and spinner mode ... selecting spinner mode for latest versions
final int MODE_SPINNER = 2;
Class<?> styleableClass = Class.forName("com.android.internal.R$styleable");
Field timePickerStyleableField = styleableClass.getField("TimePicker");
int[] timePickerStyleable = (int[]) timePickerStyleableField.get(null);
final TypedArray a = context.obtainStyledAttributes(null, timePickerStyleable, android.R.attr.timePickerStyle, 0);
Field timePickerModeStyleableField = styleableClass.getField("TimePicker_timePickerMode");
int timePickerModeStyleable = timePickerModeStyleableField.getInt(null);
final int mode = a.getInt(timePickerModeStyleable, MODE_SPINNER);
a.recycle();
if (mode == MODE_SPINNER) {
TimePicker timePicker = (TimePicker) findField(TimePickerDialog.class, TimePicker.class, "mTimePicker").get(this);
Class<?> delegateClass = Class.forName("android.widget.TimePicker$TimePickerDelegate");
Field delegateField = findField(TimePicker.class, delegateClass, "mDelegate");
Object delegate = delegateField.get(timePicker);
Class<?> spinnerDelegateClass;
if (Build.VERSION.SDK_INT != Build.VERSION_CODES.LOLLIPOP) {
spinnerDelegateClass = Class.forName("android.widget.TimePickerSpinnerDelegate");
} else {
spinnerDelegateClass = Class.forName("android.widget.TimePickerClockDelegate");
}
if (delegate.getClass() != spinnerDelegateClass) {
delegateField.set(timePicker, null); // throw out the TimePickerClockDelegate!
timePicker.removeAllViews(); // remove the TimePickerClockDelegate views
Constructor spinnerDelegateConstructor = spinnerDelegateClass.getConstructor(TimePicker.class, Context.class, AttributeSet.class, int.class, int.class);
spinnerDelegateConstructor.setAccessible(true);
// Instantiate a TimePickerSpinnerDelegate
delegate = spinnerDelegateConstructor.newInstance(timePicker, context, null, android.R.attr.timePickerStyle, 0);
delegateField.set(timePicker, delegate); // set the TimePicker.mDelegate to the spinner delegate
// Set up the TimePicker again, with the TimePickerSpinnerDelegate
timePicker.setIs24HourView(is24HourView);
timePicker.setCurrentHour(hourOfDay);
timePicker.setCurrentMinute(minute);
timePicker.setOnTimeChangedListener(this);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private static Field findField(Class objectClass, Class fieldClass, String expectedName) {
try {
Field field = objectClass.getDeclaredField(expectedName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {} // ignore
// search for it if it wasn't found under the expected ivar name
for (Field searchField : objectClass.getDeclaredFields()) {
if (searchField.getType() == fieldClass) {
searchField.setAccessible(true);
return searchField;
}
}
return null;
}
}
Настроить время max / min нет, но, возможно, он работает, если вы расширяете onTimeChanged
или updateTime
, вы можете не допустить, чтобы время было установлено на значение за пределами ваших границ.
Вы можете просто использовать пользовательский TimePicker с отражением для установки значений.
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
try {
Class<?> classForid = Class.forName("com.android.internal.R$id");
Field field = classForid.getField("minute");
NumberPicker mMinuteSpinner = (NumberPicker) findViewById(field.getInt(null));
mMinuteSpinner.setMinValue(5);
mMinuteSpinner.setMaxValue((60 / timeInterval) - 1);
List<String> displayedValues = new ArrayList<>();
for (int i = 0; i < 60; i += timeInterval)
displayedValues.add(String.format("%02d", i));
mMinuteSpinner.setDisplayedValues(displayedValues.toArray(new String[0]));
mMinuteSpinner.setWrapSelectorWheel(true);
} catch (Exception e) {
e.printStackTrace();
}
}
Таким образом, вы можете установить, какие значения вы хотите
Надеюсь, что эта работа отлично работает со мной ...
Установите максимальное время для выбора времени.
timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
if (!mIsOnTimeChanged) {
mIsOnTimeChanged = true;
Calendar c = Calendar.getInstance();
//get the selected day if it is before today allow AM and PM trick
//else apply rules
int selected_year = datePicker.getYear();
int selected_month = datePicker.getMonth();
int selected_day = datePicker.getDayOfMonth();
int today = c.get(Calendar.DAY_OF_MONTH);
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int hour = c.get(Calendar.HOUR);
hour += 12;
int min = c.get(Calendar.MINUTE);
//Check if user enter hh | mm | more than current reset the timePicker with the current time
//http://stackoverflow.com/questions/2659954/timepickerdialog-and-am-or-pm
if ((hourOfDay == hour | hour < hourOfDay | hourOfDay > hour | hour > hourOfDay | minute > min) && (selected_month == month && selected_day == today && selected_year == year)) {
int AM_PM_Value = hourOfDay;
Calendar datetime = Calendar.getInstance();
int hour_without_24 = (hour - 12);
if ((datetime.get(Calendar.AM_PM) == Calendar.AM) && (hourOfDay > hour_without_24)) {
//set AM
timePicker.setCurrentHour(hour - 12);
}
if (hourOfDay == (hour - 12) && minute > min) {
timePicker.setCurrentMinute(min);
}
if (hourOfDay > hour && datetime.get(Calendar.AM_PM) != Calendar.AM) {
timePicker.setCurrentHour(hour);
if (minute > min) {
timePicker.setCurrentMinute(min);
}
}
} else if (selected_month != month | selected_day != today | selected_year != year) {
} else if (hourOfDay == hour && minute > min) {
timePicker.setCurrentMinute(min);
} else if (hourOfDay > hour) {
timePicker.setCurrentHour(hour);
if (minute > min) {
timePicker.setCurrentMinute(min);
}
}
//
isTimePickerChanged = true;
String AM_PM;
if (hourOfDay < 12) {
AM_PM = "AM";
} else {
AM_PM = "PM";
}
//to set as 12 hour
time_format = (hourOfDay + ":" + minute + ":" + "00");
if (hourOfDay > 12) {
hourOfDay = (hourOfDay - 12);
}
st_time = (hourOfDay + ":" + pad(minute) + " " + AM_PM);
mIsOnTimeChanged = false;
}
}
});
Я принял решение @ Zarooka в качестве отправной точки. Я думаю, что нашел ошибку. Если у вас было начальное время, которое уже было вне диапазона, то вы больше не могли его перемещать, потому что любой «onChanged» отклонялся. Вот почему я расширил setMax и setMin, чтобы перейти в допустимый диапазон при настройке mins / maxs.
package de.appdream.garooda.view;
import java.util.Calendar;
import java.util.Date;
import android.app.TimePickerDialog;
import android.content.Context;
import android.text.format.DateFormat;
import android.widget.TimePicker;
import java.lang.reflect.Field;
public class GaroodaTimePickerDialog extends TimePickerDialog {
private int minHour = -1;
private int minMinute = -1;
private int maxHour = 25;
private int maxMinute = 61;
private int currentHour = 0;
private int currentMinute = 0;
private Calendar calendar = Calendar.getInstance();
//private DateFormat dateFormat;
public GaroodaTimePickerDialog(Context context, OnTimeSetListener callBack, int hour, int minute,
boolean is24HourView) {
super(context, callBack, hour, minute, is24HourView);
currentHour = hour;
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;
Calendar min = Calendar.getInstance();
Calendar existing = Calendar.getInstance();
min.set(Calendar.HOUR_OF_DAY, minHour);
min.set(Calendar.MINUTE, minMinute);
existing.set(Calendar.HOUR_OF_DAY, currentHour);
existing.set(Calendar.MINUTE, currentMinute);
if (existing.before(min)) {
currentHour = minHour;
currentMinute = minMinute;
updateTime(currentHour, currentMinute);
}
}
public void setMax(int hour, int minute) {
maxHour = hour;
maxMinute = minute;
Calendar max = Calendar.getInstance();
Calendar existing = Calendar.getInstance();
max.set(Calendar.HOUR_OF_DAY, maxHour);
max.set(Calendar.MINUTE, maxMinute);
existing.set(Calendar.HOUR_OF_DAY, currentHour);
existing.set(Calendar.MINUTE, currentMinute);
if (existing.after(max)) {
currentHour = maxHour;
currentMinute = maxMinute;
updateTime(currentHour, currentMinute);
}
}
@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);
}
}
После рефакторированного кода скрипача:
public class RangeTimePickerDialog extends TimePickerDialog {
private int mMinHour = -1;
private int mMinMinute = -1;
private int mMaxHour = 100;
private int mMaxMinute = 100;
private int mCurrentHour;
private int mCurrentMinute;
public RangeTimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay,
int minute, boolean is24HourView) {
super(context, callBack, hourOfDay, minute, is24HourView);
mCurrentHour = hourOfDay;
mCurrentMinute = minute;
// Somehow the onTimeChangedListener is not set by TimePickerDialog
// in some Android Versions, so, Adding the listener using
// reflections
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) {
mMinHour = hour;
mMinMinute = minute;
}
public void setMax(int hour, int minute) {
mMaxHour = hour;
mMaxMinute = minute;
}
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
super.onTimeChanged(view, hourOfDay, minute);
boolean validTime;
if (((hourOfDay < mMinHour ) || (hourOfDay == mMinHour && minute < mMinMinute))
|| ((hourOfDay > mMaxHour) || (hourOfDay == mMaxHour && minute > mMaxMinute))) {
validTime = false;
} else {
validTime = true;
}
if (validTime) {
mCurrentHour = hourOfDay;
mCurrentMinute = minute;
} else {
updateTime(mCurrentHour, mCurrentMinute);
}
}
}
Надеюсь, это поможет. Я использовал библиотеку времени Joda.
public class RangeTimePicker extends TimePicker implements
TimePicker.OnTimeChangedListener {
private int mMinHour = -1;
private int mMinMinute = -1;
private int mMaxHour = 25;
private int mMaxMinute = 61;
private int mCurrentHour;
private int mCurrentMinute;
public RangeTimePicker(Context context) {
super(context);
setOnTimeChangedListener(this);
}
public RangeTimePicker(Context context, AttributeSet attrs) {
super(context, attrs);
setOnTimeChangedListener(this);
}
public RangeTimePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnTimeChangedListener(this);
}
public void setMaxTime(int hourIn24, int minute) {
mMaxHour = hourIn24;
mMaxMinute = minute;
LocalTime currentTime = LocalTime.now();
LocalTime maxTime = new LocalTime(mMaxHour, mMaxMinute);
if (currentTime.isAfter(maxTime)) {
this.setCurrentHour(mCurrentHour = currentTime.getHourOfDay());
this.setCurrentMinute(
mCurrentMinute = currentTime.getMinuteOfHour());
}
}
public void setMinTime(int hourIn24, int minute) {
mMinHour = hourIn24;
mMinMinute = minute;
LocalTime currentTime = LocalTime.now();
LocalTime minTime = new LocalTime(mMinHour, mMinMinute);
if (currentTime.isBefore(minTime)) {
this.setCurrentHour(mCurrentHour = minTime.getHourOfDay());
this.setCurrentMinute(mCurrentMinute = minTime.getMinuteOfHour());
}
}
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
boolean validTime = true;
if (hourOfDay < mMinHour || (hourOfDay == mMinHour
&& minute < mMinMinute)) {
validTime = false;
}
if (hourOfDay > mMaxHour || (hourOfDay == mMaxHour
&& minute > mMaxMinute)) {
validTime = false;
}
if (validTime) {
mCurrentHour = hourOfDay;
mCurrentMinute = minute;
}
setCurrentHour(mCurrentHour);
setCurrentMinute(mCurrentMinute);
}
}