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 Numberpicker 小数

Android零基础入门第58节:数值选择器NumberPicker

为啥虚拟键盘不适用于 Qt 中的 QDialog 文本框?

windowSoftInputMode:当键盘提示文本时,adjustResize 不适用于数字键盘

更改 android numberpicker 分隔线颜色