2

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()不会被执行。只有当用户手动滚动数字选择器时,语句才会执行。我希望在单击按钮时发生同样的情况。

4

2 回答 2

3

这实际上是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);
    }
});
于 2016-06-26T07:29:52.767 回答
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 
    }
});
于 2016-06-26T07:16:59.093 回答