我有一个NumberPicker,它有一个格式化程序,可以在NumberPicker旋转或手动输入值时格式化显示的数字。这样可以正常工作,但是当第一次显示NumberPicker并用setValue(0)
初始化它时,0不会被格式化(它应该显示为“ - ”而不是0)。一旦我从那一点开始旋转NumberPicker,一切正常。
如何强制NumberPicker始终格式化 - 在第一次渲染时以及在使用键盘手动输入数字时?
这是我的格式化程序
public class PickerFormatter implements Formatter {
private String mSingle;
private String mMultiple;
public PickerFormatter(String single, String multiple) {
mSingle = single;
mMultiple = multiple;
}
@Override
public String format(int num) {
if (num == 0) {
return "-";
}
if (num == 1) {
return num + " " + mSingle;
}
return num + " " + mMultiple;
}
}
我将格式化程序添加到setFormatter()
的选择器中,这就是我对选择器所做的一切。
picker.setMaxValue(max);
picker.setMinValue(min);
picker.setFormatter(new PickerFormatter(single, multiple));
picker.setWrapSelectorWheel(wrap);
答案 0 :(得分:25)
我也遇到了这个烦人的小bug。使用this answer中的一种技术来提出令人讨厌但有效的修复方法。
NumberPicker picker = (NumberPicker)view.findViewById(id.picker);
picker.setMinValue(1);
picker.setMaxValue(5);
picker.setWrapSelectorWheel(false);
picker.setFormatter(new NumberPicker.Formatter() {
@Override
public String format(int value) {
return my_formatter(value);
}
});
try {
Method method = picker.getClass().getDeclaredMethod("changeValueByOne", boolean.class);
method.setAccessible(true);
method.invoke(picker, true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
在实例化我的数字选择器之后立即调用该私有changeValueByOne
方法似乎足以使格式化程序表现得如此。数字选择器出现很好,干净,第一个值格式正确。就像我说的那样,讨厌但有效。
答案 1 :(得分:25)
dgel's solution对我不起作用:当我点击选择器时,格式化会再次消失。如果未使用EditText
,则NumberPicker
内的setDisplayValues
上设置的输入过滤器会导致此错误。所以我提出了这个解决方法:
Field f = NumberPicker.class.getDeclaredField("mInputText");
f.setAccessible(true);
EditText inputText = (EditText)f.get(mPicker);
inputText.setFilters(new InputFilter[0]);
答案 2 :(得分:11)
我遇到了同样的问题而我使用了setDisplayedValues()
方法。
int max = 99;
String[] values = new String[99];
values[0] = “-” + mSingle
values[1] =
for(int i=2; i<=max; i++){
makeNames[i] = String.valueOf(i) + mMultiple;
}
picker.setMinValue(0);
picker.setMaxValue(max);
picker.setDisplayedValues(values)
但这不允许用户在选择器中手动设置值。
答案 3 :(得分:5)
以下解决方案适用于API 18-26 而不使用反射,并且不使用setDisplayedValues()
。
它包含两个步骤:
通过将第一个元素的可见性设置为不可见来确保显示第一个元素(我使用布局检查器查看显示时间的差异,它不符合逻辑,但View.INVISIBLE
实际上是private void initNumberPicker() {
// Inflate or create your BugFixNumberPicker class
// Do your initialization on bugFixNumberPicker...
bugFixNumberPicker.setFormatter(new NumberPicker.Formatter() {
@Override
public String format(final int value) {
// Format to your needs
return aFormatMethod(value);
}
});
// Fix for bug in Android Picker where the first element is not shown
View firstItem = bugFixNumberPicker.getChildAt(0);
if (firstItem != null) {
firstItem.setVisibility(View.INVISIBLE);
}
}
使视图可见。
public class BugFixNumberPicker extends NumberPicker {
public BugFixNumberPicker(Context context) {
super(context);
}
public BugFixNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BugFixNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean performClick() {
return false;
}
@Override
public boolean performLongClick() {
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
return false;
}
}
Subclass NumberPicker并确保没有点击事件通过,因此拾取元素在触摸时消失的故障不会发生。
$conn = mysqli_connect("localhost", "root", "", "databasename");
答案 4 :(得分:4)
如前面的回答中所述,通过反射调用私有方法changeValueByOne()
适用于API Level 16
(Android 4.1.2及更高版本),但它似乎对{{1}没有帮助但是(Android 4.0.3)!
在API级别15(及以上)对我有用的是使用您自己的自定义格式化程序来创建String数组,并使用方法API Level 15
将其传递给数字选择器。
答案 5 :(得分:3)
NoActivity提供的答案对我有用,但我只需要这样做:
View firstItem = bugFixNumberPicker.getChildAt(0);
if (firstItem != null) {
firstItem.setVisibility(View.INVISIBLE);
}
解决问题。我不需要继承NumberPicker。我没有看到拾取元素在触摸时消失的问题。
答案 6 :(得分:3)
这是我基于torvin和Sebastian的答案的解决方案。您不必继承任何子类或使用反射。
View editView = numberPicker.getChildAt(0);
if (editView != null && editView instanceof EditText) {
// Remove default input filter
((EditText) editView).setFilters(new InputFilter[0]);
}
答案 7 :(得分:1)
我设法通过调用
来修复它picker.invalidate();
设置格式化程序后。
答案 8 :(得分:1)
Kotlin 版本基于 Nikolai's 答案
private fun initNumberPicker() {
nrPicker.children.iterator().forEach {
if (it is EditText) it.filters = arrayOfNulls(0) // remove default input filter
}
}
答案 9 :(得分:0)
如果所选索引不为0,则改进了Nikolai的答案。虽然对性能没有太大帮助,但可以解决问题。
for(index in numberPicker.minValue..numberPicker.maxValue) {
val editView = numberPicker.getChildAt(index-numberPicker.minValue)
if (editView != null && editView is EditText) {
// Remove default input filter
(editView as EditText).filters = arrayOfNulls(0)
}
}