list-picker not ready

This commit is contained in:
Hristo Hristov
2016-12-08 01:29:52 +02:00
committed by Hristo Hristov
parent fac4f42503
commit 007b78325c
5 changed files with 91 additions and 39 deletions

View File

@ -108,8 +108,7 @@ export class Property<T extends ViewBase, U> implements PropertyDescriptor {
}); });
} }
let nativeObject = this.nativeView; if (this.nativeView) {
if (nativeObject) {
this[native] = unboxedValue; this[native] = unboxedValue;
} }
@ -215,8 +214,7 @@ export class CoercibleProperty<T extends ViewBase, U> implements PropertyDescrip
}); });
} }
let nativeObject = this.nativeView; if (this.nativeView) {
if (nativeObject) {
this[native] = unboxedValue; this[native] = unboxedValue;
} }

View File

@ -1,5 +1,5 @@
import { ListPicker as ListPickerDefinition, ItemsSource } from "ui/list-picker"; import { ListPicker as ListPickerDefinition, ItemsSource } from "ui/list-picker";
import { View, Property } from "ui/core/view"; import { View, Property, CoercibleProperty } from "ui/core/view";
export * from "ui/core/view"; export * from "ui/core/view";
@ -7,30 +7,43 @@ export class ListPickerBase extends View implements ListPickerDefinition {
public selectedIndex: number; public selectedIndex: number;
public items: any[] | ItemsSource; public items: any[] | ItemsSource;
public isItemsSource: boolean;
public _getItemAsString(index: number): any { public _getItemAsString(index: number): any {
if (!this.items) { let items = this.items;
if (!items) {
return " "; return " ";
} }
let getItem = (<ItemsSource>this.items).getItem; let item = this.isItemsSource ? (<ItemsSource>this.items).getItem(index) : this.items[index];
let item = typeof getItem === "function" ? getItem(index) : this.items[index]; return (item === undefined || item === null) ? index + "" : item + "";
return item === undefined || item === null ? index + "" : item + "";
}
protected getSelectedIndex(items: any[] | ItemsSource): number {
let maxValue = items && items.length > 0 ? items.length - 1 : 0;
let selectedIndex = this.selectedIndex;
if (selectedIndex < 0 || selectedIndex > maxValue) {
selectedIndex = 0;
}
return selectedIndex;
} }
} }
export const selectedIndexProperty = new Property<ListPickerBase, number>({ name: "selectedIndex", defaultValue: -1, valueConverter: (v) => parseInt(v) }); export const selectedIndexProperty = new CoercibleProperty<ListPickerBase, number>({
name: "selectedIndex", defaultValue: -1,
valueConverter: (v) => parseInt(v),
coerceValue: (target, value) => {
let items = target.items;
if (items) {
let max = items.length - 1;
if (value > max) {
value = max;
}
} else {
value = -1;
}
return value;
}
});
selectedIndexProperty.register(ListPickerBase); selectedIndexProperty.register(ListPickerBase);
export const itemsProperty = new Property<ListPickerBase, any[] | ItemsSource>({ name: "items" }); export const itemsProperty = new Property<ListPickerBase, any[] | ItemsSource>({
name: "items", valueChanged: (target, oldValue, newValue) => {
let getItem = newValue && (<ItemsSource>newValue).getItem;
target.isItemsSource = typeof getItem === "function";
selectedIndexProperty.coerce(target);
}
});
itemsProperty.register(ListPickerBase); itemsProperty.register(ListPickerBase);

View File

@ -1,4 +1,4 @@
import { ListPickerBase, selectedIndexProperty, itemsProperty, colorProperty } from "./list-picker-common"; import { ListPickerBase, selectedIndexProperty, itemsProperty, colorProperty, Color } from "./list-picker-common";
import { ItemsSource } from "ui/list-picker"; import { ItemsSource } from "ui/list-picker";
export * from "./list-picker-common"; export * from "./list-picker-common";
@ -33,19 +33,44 @@ class ValueChangeListener implements android.widget.NumberPicker.OnValueChangeLi
} }
} }
function getEditText(picker: android.widget.NumberPicker): android.widget.EditText {
for (let i = 0, count = picker.getChildCount(); i < count; i++) {
let child = picker.getChildAt(i);
if (child instanceof android.widget.EditText) {
return child;
}
}
return null;
}
let selectorWheelPaintField: java.lang.reflect.Field;
function getSelectorWheelPaint(picker: android.widget.NumberPicker): android.graphics.Paint {
if (!selectorWheelPaintField) {
selectorWheelPaintField = picker.getClass().getDeclaredField("mSelectorWheelPaint");
selectorWheelPaintField.setAccessible(true);
}
return selectorWheelPaintField.get(picker);
}
export class ListPicker extends ListPickerBase { export class ListPicker extends ListPickerBase {
private _android: android.widget.NumberPicker; private _android: android.widget.NumberPicker;
private _valueChangedListener: android.widget.NumberPicker.OnValueChangeListener; private _valueChangedListener: android.widget.NumberPicker.OnValueChangeListener;
private _formatter: android.widget.NumberPicker.Formatter; private _formatter: android.widget.NumberPicker.Formatter;
private _editText: android.widget.EditText; private _editText: android.widget.EditText;
private itemsSet: boolean; private _selectorWheelPaint: android.graphics.Paint;
get android(): android.widget.NumberPicker { get android(): android.widget.NumberPicker {
return this._android; return this._android;
} }
public _createUI() { public _createUI() {
this._android = new android.widget.NumberPicker(this._context); this._android = new android.widget.NumberPicker(this._context);
this._editText = getEditText(this._android);
this._selectorWheelPaint = getSelectorWheelPaint(this._android);
this._android.setDescendantFocusability(android.widget.NumberPicker.FOCUS_BLOCK_DESCENDANTS); this._android.setDescendantFocusability(android.widget.NumberPicker.FOCUS_BLOCK_DESCENDANTS);
this._android.setMinValue(0); this._android.setMinValue(0);
@ -55,24 +80,21 @@ export class ListPicker extends ListPickerBase {
let formatter = this._formatter || new Formatter(new WeakRef(this)); let formatter = this._formatter || new Formatter(new WeakRef(this));
this._android.setFormatter(this._formatter); this._android.setFormatter(this._formatter);
let valueChangedListener = this._valueChangedListener || new ValueChangeListener(new WeakRef(this)); this._valueChangedListener = this._valueChangedListener || new ValueChangeListener(new WeakRef(this));
this._android.setOnValueChangedListener(this._valueChangedListener); this._android.setOnValueChangedListener(this._valueChangedListener);
//Fix the disappearing selected item. //Fix the disappearing selected item.
//HACK: http://stackoverflow.com/questions/17708325/android-numberpicker-with-formatter-does-not-format-on-first-rendering/26797732 //HACK: http://stackoverflow.com/questions/17708325/android-numberpicker-with-formatter-does-not-format-on-first-rendering/26797732
var mInputTextField = java.lang.Class.forName("android.widget.NumberPicker").getDeclaredField("mInputText");
mInputTextField.setAccessible(true);
this._editText = <android.widget.EditText>mInputTextField.get(this._android);
this._editText.setFilters([]); this._editText.setFilters([]);
//Since the Android NumberPicker has to always have at least one item, i.e. minValue=maxValue=value=0, we don't want this zero showing up when this.items is empty. //Since the Android NumberPicker has to always have at least one item, i.e. minValue=maxValue=value=0, we don't want this zero showing up when this.items is empty.
this._editText.setText(" ", android.widget.TextView.BufferType.NORMAL); this._editText.setText(" ", android.widget.TextView.BufferType.NORMAL);
this.android.setWrapSelectorWheel(false); this._android.setWrapSelectorWheel(false);
} }
private updateSelectedValue(): void { private updateSelectedValue(): void {
let selectedIndex = this.getSelectedIndex(this.items); let selectedIndex = this.selectedIndex;
this.android.setValue(selectedIndex); this.android.setValue(selectedIndex);
} }
@ -87,12 +109,12 @@ export class ListPicker extends ListPickerBase {
private _fixNumberPickerRendering() { private _fixNumberPickerRendering() {
//HACK: Force the stubborn NumberPicker to render correctly when we have 0 or 1 items. //HACK: Force the stubborn NumberPicker to render correctly when we have 0 or 1 items.
this.android.setFormatter(null); this._android.setFormatter(null);
this.android.setFormatter(this._formatter); //Force the NumberPicker to call our Formatter this._android.setFormatter(this._formatter); //Force the NumberPicker to call our Formatter
if (this._editText) { if (this._editText) {
this._editText.setFilters([]); this._editText.setFilters([]);
}
this._editText.invalidate(); //Force the EditText to redraw this._editText.invalidate(); //Force the EditText to redraw
}
this.android.invalidate(); this.android.invalidate();
} }
@ -122,7 +144,24 @@ export class ListPicker extends ListPickerBase {
} }
} }
get [colorProperty.native](): number { get [colorProperty.native](): { wheelColor: number, textColor: number } {
return return {
wheelColor: this._selectorWheelPaint.getColor(),
textColor: this._editText.getTextColors().getDefaultColor()
}
}
set [colorProperty.native](value: { wheelColor: number, textColor: number } | Color) {
let color: number;
let wheelColor: number;
if (value instanceof Color) {
color = wheelColor = value.android;
} else {
color = value.textColor;
wheelColor = value.wheelColor;
}
this._selectorWheelPaint.setColor(wheelColor);
this._editText.setTextColor(color);
} }
} }

View File

@ -7,7 +7,6 @@ export class ListPicker extends ListPickerBase {
private _ios: UIPickerView; private _ios: UIPickerView;
private _dataSource: ListPickerDataSource; private _dataSource: ListPickerDataSource;
private _delegate: ListPickerDelegateImpl; private _delegate: ListPickerDelegateImpl;
private itemsSet: boolean;
constructor() { constructor() {
super(); super();
@ -32,7 +31,7 @@ export class ListPicker extends ListPickerBase {
} }
private updateSelectedValue(): void { private updateSelectedValue(): void {
let selectedIndex = this.getSelectedIndex(this.items); let selectedIndex = this.selectedIndex;
if (selectedIndex >= 0) { if (selectedIndex >= 0) {
this.ios.selectRowInComponentAnimated(selectedIndex, 0, false); this.ios.selectRowInComponentAnimated(selectedIndex, 0, false);
} }

View File

@ -154,10 +154,12 @@ export const itemsProperty = new Property<TabViewBase, TabViewItemBase[]>({
itemsProperty.register(TabViewBase); itemsProperty.register(TabViewBase);
export const selectedIndexProperty = new CoercibleProperty<TabViewBase, number>({ export const selectedIndexProperty = new CoercibleProperty<TabViewBase, number>({
name: "selectedIndex", defaultValue: -1, affectsLayout: isIOS, valueChanged: (target, oldValue, newValue) => { name: "selectedIndex", defaultValue: -1, affectsLayout: isIOS,
valueChanged: (target, oldValue, newValue) => {
let args = { eventName: TabViewBase.selectedIndexChangedEvent, object: this, oldIndex: oldValue, newIndex: newValue }; let args = { eventName: TabViewBase.selectedIndexChangedEvent, object: this, oldIndex: oldValue, newIndex: newValue };
target.notify(args); target.notify(args);
}, coerceValue: (target, value) => { },
coerceValue: (target, value) => {
let items = target.items; let items = target.items;
if (items) { if (items) {
let max = items.length - 1; let max = items.length - 1;
@ -169,7 +171,8 @@ export const selectedIndexProperty = new CoercibleProperty<TabViewBase, number>(
} }
return value; return value;
} },
valueConverter: (v) => parseInt(v)
}); });
selectedIndexProperty.register(TabViewBase); selectedIndexProperty.register(TabViewBase);