I'm using the below function to detect the last final value when user complete their scroll select on NumberPicker. The getValue() would then get the latest value updated.
numberPicker.setOnScrollListener(new NumberPicker.OnScrollListener() {
@Override
public void onScrollStateChange(NumberPicker numberPicker, int scrollState) {
if (scrollState == NumberPicker.OnScrollListener.SCROLL_STATE_IDLE) {
int value = numberPicker.getValue();
}
}
});
However, then I found out that, in the event the scroll-touch end not on a definite position of a value, but in between 2 values (e.g. between 1 and 2, but slightly closer towards 2), after letting go the scroll, the function trigger captured the getValue as 1, but the scroll will auto-complete it's scroll to centralize at 2. Therefore the last updated value of the NumberPicker is then set to 2 (not 1 i.e. as was captured in my function above).
How could I get the last updated value of the NumberPicker? Or perhaps a way to detect the final auto scroll of the NumberPicker (when it is centralizing to a specific value)?
FYI. One option is to use setOnValueChangedListener
. However this is not ideal for my case, as it capture every single value change even the NumberPicker scrolling is in progress.
Thanks!
To solve this, I add both OnValueChange and OnScrollListener to NumberPicker. I made private field to keep current scroll state. Both listener interfaces are implemented by same class. onValueChangeListener method checks scroll state, and if it's idle - execute some code. This works for me. Looks something like that:
public class MainActivity extends AppCompatActivity {
private NumberPicker np;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
np = (NumberPicker) findViewById(R.id.picker);
PickerListener listener = new PickerListener();
np.setOnScrollListener(listener);
np.setOnValueChangedListener(listener);
}
private void update(){
//your code here
}
private class PickerListener implements NumberPicker.OnScrollListener, NumberPicker.OnValueChangeListener {
private int scrollState=0;
@Override
public void onScrollStateChange(NumberPicker view, int scrollState) {
this.scrollState=scrollState;
if (scrollState==SCROLL_STATE_IDLE){
update();
}
}
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
if (scrollState==0){
update();
}
}
}
After so many years, this seems still a known challenge? I feel the last value should be what users intend to use in most of the cases. I wish the Android ADK could make it easier ...
Anyway, I found the solutions above are acceptable but I use the following evolved from all the above:
myPicker.setOnScrollListener({ picker, state ->
if(state == SCROLL_STATE_IDLE) {
picker.postDelayed( { // to make sure value is in picker regardless the order of scroll or value change events
val newVal = picker.value
// use the value and hidePicker()
}, 500)
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With