NumberPicker 不适用于键盘
Posted
技术标签:
【中文标题】NumberPicker 不适用于键盘【英文标题】:NumberPicker doesn't work with keyboard 【发布时间】:2013-09-27 12:11:33 【问题描述】:在activity_main.xml
:
<NumberPicker
android:id="@+id/numberPicker1"
android:layout_
android:layout_
android:layout_below="@+id/textView2"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp" />
在MainActivity.java
里面oncreate
:
NumberPicker numberPicker1 = (NumberPicker) findViewById(R.id.numberPicker1);
numberPicker1.setMinValue(1);
numberPicker1.setMaxValue(20);
当我用键盘编辑值时,我以编程方式获得的值不会改变,但如果我按下+
然后-
它可以工作。
如何在不按+
和-
的情况下使其工作?
编辑:
我使用 Melih Altıntaş 的代码创建了一个新项目,它显示了一个全新的数字选择器!! (您用手指滑动而无法输入文字的地方)。然后我与我的真实项目进行比较,我看到了android:theme="@android:style/Theme.NoTitleBar"
。我在新项目中添加了它,然后数字选择器变成了我习惯的那个。
【问题讨论】:
我也遇到了同样的问题,有没有人想出一个更好的答案呢? 【参考方案1】:如果有人想要一个简单的解决方法,只需在保存值之前添加以下代码。
numberPicker.clearFocus();
【讨论】:
IMO 这是最简单的修复方法,也是最好的:它有效。 你才是真正的MVP 毕竟这么多年来让它工作仍然很痛苦,这是非常需要的,非常感谢! 这个!!!使用 TimePicker 为我节省了很多时间,它里面有 2 个 NumberPicker(如果你使用 timePickerMode="spinner")【参考方案2】:NumberPicker
不是为这种交互而设计的。当您使用键盘更改值时,您将直接从NumberPicker
更改小部件,而小部件本身看不到此更改,因此这就是您最终得到最后一个存储值的原因。要解决这个问题,您需要一些 hacky 代码,但实际上并不推荐这样做,因为您需要访问底层 EditText
(假设手机制造商一开始没有更改此代码):
private EditText findInput(ViewGroup np)
int count = np.getChildCount();
for (int i = 0; i < count; i++)
final View child = np.getChildAt(i);
if (child instanceof ViewGroup)
findInput((ViewGroup) child);
else if (child instanceof EditText)
return (EditText) child;
return null;
然后您将使用此代码在找到的EditText
上设置TextWatcher
以查看它何时被手动修改(并让NumberPicker
知道此更改):
EditText input = findInput(np);
TextWatcher tw = new TextWatcher()
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count)
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after)
@Override
public void afterTextChanged(Editable s)
if (s.toString().length() != 0)
Integer value = Integer.parseInt(s.toString());
if (value >= np.getMinValue())
np.setValue(value);
;
input.addTextChangedListener(tw);
另一种选择是自己实现NumberPicker
小部件并插入您的目标功能。
【讨论】:
你测试了吗?我的意思是,你确定它必须工作吗?因为它使用Invalid int: ""
使我的应用程序崩溃。 (顺便说一句,我将 input.addTextChangedListener(tw);
移到底部,因为不会定义 tw)
@Mageek 行np.setValue(Integer.parseInt(s.toString()));
应该包含在检查字符串是否不为空(例如删除所有数字时):if (s.toString().length() == 0) np.setValue().getMinValue(); else np.setValue(Integer.parseInt(s.toString()));
你确定是np.setValue().getMinValue();
吗?因为没有论据……(对不起,我还是java和android编程的初学者)
@Mageek 不,我的错误。这个想法是在文本为空时设置最小值:np.setValue(np.getMinValue());
。
但是现在,几乎不可能编辑数字了。示例:它是7
,您想输入2
。首先,你用退格键和 PAF 擦除它变成1
...【参考方案3】:
我看到您已经有了答案,但这可能对其他人有用。您可以扩展 android.widget.NumberPicker 并自己制作可以配置 EditText 的位置。当您在软键盘上键入时,NumberPicker 的值会立即设置为您正在键入的值。
public class MyNumberPicker extends android.widget.NumberPicker
private EditText eText;
public MyNumberPicker(Context context, AttributeSet attrs)
super(context, attrs);
@Override
public void addView(View child)
super.addView(child);
initEditText(child);
@Override
public void addView(View child, int index, android.view.ViewGroup.LayoutParams params)
super.addView(child, index, params);
initEditText(child);
@Override
public void addView(View child, android.view.ViewGroup.LayoutParams params)
super.addView(child, params);
initEditText(child);
public void initEditText(View view)
if(view instanceof EditText)
EditText eText = (EditText) view;
eText.addTextChangedListener(new TextWatcher()
@Override
public void afterTextChanged(Editable arg0)
// TODO Auto-generated method stub
@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3)
// TODO Auto-generated method stub
@Override
public void onTextChanged(CharSequence s, int start, int before, int count)
try
int num = Integer.parseInt(s.toString());
setValue(num); //this line changes the value of your numberpicker
catch(NumberFormatException E)
//do your catching here
);
在您的 XML 文件中输入以下内容:
<com.mypackage.MyNumberPicker
android:id="@+id/numberPicker1"
android:layout_
android:layout_ />
【讨论】:
【参考方案4】:您必须按Done
按钮才能以编程方式更改值。
【讨论】:
我的现在工作了,所以如果你按下明确的焦点,你让听众按下肯定按钮,它应该可以工作。在这个阶段有两个假设。为什么它起作用是因为假设您已经输入了文本,并且当您在此方法的内部实现中调用 clearFocus 时,将获取该值并将其设置在内部数字选择器 edittext【参考方案5】:NumberPicker np = (NumberPicker) findViewById(R.id.numberPicker1);
String[] nums = new String[20];
for(int i=0; i<nums.length; i++)
nums[i] = Integer.toString(i);
np.setMinValue(1);
np.setMaxValue(20);
np.setWrapSelectorWheel(false);
np.setDisplayedValues(nums);
np.setValue(1);
【讨论】:
我刚刚发现了一些非常奇怪的东西,请参阅我的编辑。你知道该怎么做吗? 这很奇怪 android:theme="@android:style/Theme.Light.NoTitleBar" 和状态栏有关 如果你想去掉状态栏,那就用吧 我决定尝试这种方法,但遇到了同样的问题。不幸的是,这似乎根本没有任何区别,数字选择器仍然以完全相同的方式显示并执行完全相同的操作。我没有使用@Mageek 提到的主题,很奇怪。谁能提供进一步的见解?【参考方案6】:它不起作用的原因是,如果您查看 NumberPicker 中 setValue 的实现,它会调用另一个方法 setValueInternal(int, boolean),它采用 2 个参数作为新值,当然还有代表的 bugger boolean它是否应该通知 UI 任何更改。猜猜看,在 setValue 中,布尔值始终为 false。该死的。但是还有一个技巧,我看到 validateInputTextView 实际上正确地执行了它,并且它在编辑文本没有焦点时调用。也许在正确的时间清除焦点会做应该做的事情。
【讨论】:
以上是关于NumberPicker 不适用于键盘的主要内容,如果未能解决你的问题,请参考以下文章
将 Android NumberPicker 限制为用于数字输入的数字键盘(不是 Alpha 键盘)
Android零基础入门第58节:数值选择器NumberPicker