Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change NumberPicker's value with animation?

I've created an application for Android, in which there is a NumberPicker. And I need to change the value of this NumberPicker but with a smooth animation like when you touch it and change its value.

For example, assume the current value is 1 and it's going to be 5, I want the NumberPicker to spin from 1 to 2 then to 3 and so on. But I want it to spin not just instantly change the values!

If I use the following code:

numberPicker.setValue(5);

its value will instantly change to 5, but I want it to roll up from 1 to 5 like when you manually touch it and make it spin.

like image 681
Mehran Avatar asked Nov 21 '12 19:11

Mehran


2 Answers

Thanks to @passy for the answer. Can be further simplified with a Kotlin Extension function:

fun NumberPicker.animateChange(isIncrement: Boolean) {
    Handler().post {
        try {
            javaClass.getDeclaredMethod("changeValueByOne", Boolean::class.javaPrimitiveType).also { function ->
                function.isAccessible = true
                function.invoke(this, isIncrement)
            }
        } catch (e: Exception) {
            Log.e(javaClass.simpleName, e.message)
        }
    }
}
like image 102
Jules Avatar answered Sep 21 '22 09:09

Jules


I solved it via refelction

        /**
         * using reflection to change the value because
         * changeValueByOne is a private function and setValue
         * doesn't call the onValueChange listener.
         * 
         * @param higherPicker
         *            the higher picker
         * @param increment
         *            the increment
         */
        private void changeValueByOne(final NumberPicker higherPicker, final boolean increment) {

            Method method;
            try {
                // refelction call for
                // higherPicker.changeValueByOne(true);
                method = higherPicker.getClass().getDeclaredMethod("changeValueByOne", boolean.class);
                method.setAccessible(true);
                method.invoke(higherPicker, increment);

            } catch (final NoSuchMethodException e) {
                e.printStackTrace();
            } catch (final IllegalArgumentException e) {
                e.printStackTrace();
            } catch (final IllegalAccessException e) {
                e.printStackTrace();
            } catch (final InvocationTargetException e) {
                e.printStackTrace();
            }
        }

works perfect. I don't know why this method is private

like image 34
passsy Avatar answered Sep 19 '22 09:09

passsy