【问题标题】:How to call Number Picker onvaluechange method from button onclick?如何从按钮 onclick 调用 Number Picker onvaluechange 方法?
【发布时间】:2016-06-26 07:04:20
【问题描述】:

xml 中的数字选择器:

<NumberPicker
        android:id="@+id/np"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:layout_weight="1" />

这是按钮:

<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:padding="30dp"
    android:text="Any text!"
    android:background="@drawable/round_button" />

数字选择器上的 OnValueChangedListener:

//Set a value change listener for NumberPicker
    numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal){

            //Statement goes here...

        }
    });

每当用户更改值时,onvaluechange 中的语句都会按应有的方式执行。但我想使用按钮更新数字选择器的值。

现在,我为按钮设置了一个 onclicklistener:

b1 = (Button) rootView.findViewById(R.id.button);
    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Increment NumberPicker value by 1
            numberPicker.setValue(numberPicker.getValue() + 1);
        }
    });

这有效,它将数字选择器的值增加 1,但它不会通知数字选择器该值已更改,因此,onValueChange() 中的代码不会被执行。只有当用户手动滚动数字选择器时,语句才会执行。我希望在单击按钮时发生同样的情况。

【问题讨论】:

    标签: android android-number-picker


    【解决方案1】:

    这实际上是NumberPicker 小部件的正确行为。 如果你查看它的源代码,你会看到:

    public void setValue(int value) {
        setValueInternal(value, false);
    }
    

    这里是setValueInternal 方法:

    private void setValueInternal(int current, boolean notifyChange) {
        if (mValue == current) {
            return;
        }
        // Wrap around the values if we go past the start or end
        if (mWrapSelectorWheel) {
            current = getWrappedSelectorIndex(current);
        } else {
            current = Math.max(current, mMinValue);
            current = Math.min(current, mMaxValue);
        }
        int previous = mValue;
        mValue = current;
        updateInputTextView();
        if (notifyChange) {
            notifyChange(previous, current);
        }
        initializeSelectorWheelIndices();
        invalidate();
    }
    

    如您所见,setValueInternal 由带有 notifyChange = falsesetValue 方法调用,这就是您的听众没有收到通知的原因。 setValueInternal 被声明为私有,因此您不能在不使用反射的情况下从代码中调用它。

    我的建议是这样做:

    private class NumberPickerListener implements NumberPicker.OnValueChangeListener {
    
        @Override
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
          //your code
        }
    }
    

    然后只需声明一个 NumberPickerListener 变量并在您的点击监听器中使用它:

    final NumberPickerListener numberListener = new NumberPickerListener();
    numberPicker.setOnValueChangedListener(numberListener);
    
    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            int oldValue = numberPicker.getValue();
            numberPicker.setValue(oldValue + 1);
            numberListener.onValueChange(numberPicker, oldValue, oldValue+1);
        }
    });
    

    【讨论】:

    • 感谢您指出这一点。真的很奇怪,几乎所有的 Android 组件即使在手动更改时也会通知侦听器,但 NumberPicker 却没有。
    【解决方案2】:

    有一个单独的变量供监听器使用

    NumberPicker.OnValueChangeListener np_listener = new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal){
    
                //Statement goes here...
    
            }
        }
    

    如何设置

    numberPicker.setOnValueChangedListener(np_listener);
    

    用法

    b1 = (Button) rootView.findViewById(R.id.button);
    b1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Increment NumberPicker value by 1
            numberPicker.setValue(numberPicker.getValue() + 1);
           // use it here np_listener 
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2014-10-06
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 2012-08-17
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多