如何从按钮onclick调用Number Picker onvaluechange方法?

时间:2016-06-26 07:04:21

标签: android android-number-picker

xml中的NumberPicker:

<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" />

numberpicker上的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,但它不会通知numberpicker该值已更改,因此onValueChange()内的代码不会被执行。只有当用户手动滚动数字选择器时,语句才会执行。我希望在点击按钮时发生同样的事情。

2 个答案:

答案 0 :(得分: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 
    }
});

答案 1 :(得分:2)

这实际上是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 = false 调用setValue,这就是您的侦听器未收到通知的原因。 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);
    }
});