Skip to content Skip to sidebar Skip to footer

Android Numberpicker For Floating Point Numbers

The user of our app should be able to adjust a floating point number. At the moment, I filled an ArrayAdapter with all possible values and attached it to a spinner. This solution d

Solution 1:

NumberPicker is not just for integers.. Even you can use FloatsString etc.

see this and read about it.

for tutorials :

And I had used NumberPicker long ago like this and it might be some use posting here:

NumberPicker np;
    String nums[]= {"Select Fraction","1/64","1/32","3/64","1/16","5/64","3/32","7/64","1/8","9/64","5/32","11/64","3/16","13/64","7/32","15/64","1/4","17/64","9/32","19/64","5/16","21/64","11/32","23/64","3/8","25/64","13/32","27/64","7/16","29/64"};

            np = (NumberPicker) findViewById(R.id.np);

            np.setMaxValue(nums.length-1);
            np.setMinValue(0);
            np.setWrapSelectorWheel(false);
            np.setDisplayedValues(nums);
            np.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); 

You can make ArrayList of any datatype and assign it.

Solution 2:

Another solution is to combine two numberfields into one component. See the Money Picker Example. Its advantage is that you don't have to initialize all possible double values for your spinner.

You may also need to attach special digits formatting, like "00", "0123" or other, using java.lang.String.format() function. Example is here.

  1. Add Double Picker xml-layout:

    <LinearLayoutxmlns:android = "http://schemas.android.com/apk/res/android"android:layout_width = "fill_parent"android:layout_height = "wrap_content"android:gravity = "center"><NumberPickerandroid:id = "@+id/integer_picker"android:layout_width = "wrap_content"android:layout_height = "wrap_content"android:layout_gravity = "center"/><TextViewandroid:layout_width = "wrap_content"android:layout_height = "wrap_content"android:layout_gravity = "center"android:padding = "5dp"android:text = "@string/local_separator"android:textSize = "20sp"/><NumberPickerandroid:id = "@+id/fraction_picker"android:layout_width = "wrap_content"android:layout_height = "wrap_content"android:layout_gravity = "center"/><TextViewandroid:layout_width = "wrap_content"android:layout_height = "wrap_content"android:layout_gravity = "center"android:padding = "5dp"android:text = "@string/measure_unit_sign"android:textSize = "20sp"/></LinearLayout>
  2. Add custom Double Picker class:

    import android.content.Context;
    import android.view.LayoutInflater;
    import android.widget.NumberPicker;
    
    /**
     * UI component for double (floating point) values. Can be used
     * for money and other measures.
     */publicclassDoublePickerextendsNumberPicker {
    
      privateint decimals;
      private NumberPicker integerPicker;
      private NumberPicker fractionPicker;
    
      publicDoublePicker(
        Context context) {
    
        super(
          context);
    
          LayoutInflater
            .from(
              context)
            .inflate(
              R.layout.double_picker,
              this);
    
          integerPicker =
            (NumberPicker) findViewById(
              R.id.integer_picker);
    
          fractionPicker =
            (NumberPicker) findViewById(
              R.id.fraction_picker);
      }
    
      publicintgetDecimals() {
    
        return decimals;
      }
    
      /**
       * Sets the amount of digits after separator.
       *
       * @param decimals Anount of decimals.
       */publicvoidsetDecimals(finalint decimals) {
    
        this.decimals = decimals;
    
        this.setFormatter(newDoublePicker.Formatter() {
    
          @Overridepublic String format(int i) {
    
            return String.format(
              "%." + decimals + "f",
              i);
          }
        });
      }
    
      publicvoidsetValue(double value) {
    
        integerPicker.setValue((int) value);
    
        fractionPicker.setValue(
          Integer.valueOf(
            String
              .valueOf(value)
              .split(".")
              [1]));
      }
    }
    
  3. Use new Double Picker component in your activity xml:

    <com.example.DoublePicker
      android:id ="@+id/double_picker"
      android:layout_width ="match_parent"
      android:layout_height ="wrap_content" />
    

Solution 3:

In Kotlin, you can use this handy NumberPicker extension dialog which scales your Double values into a fitting Int range and converts the Int values back to Doubles before calling any of the callback. So it basicallly hides away the fact that NumberPicker only supports Int. It just feels like NumberPicker would actually support Double, try it out!

Here's the Fragment extension you need to copy & paste:

fun Fragment.showNumberPickerDialog(
    title: String,
    value: Double,
    range: ClosedRange<Double>,
    stepSize: Double,
    formatToString: (Double) -> String,
    valueChooseAction: (Double) -> Unit
) {
    val numberPicker = NumberPicker(context).apply {
        setFormatter { formatToString(it.toDouble() * stepSize) }
        wrapSelectorWheel = false

        minValue = (range.start / stepSize).toInt()
        maxValue = (range.endInclusive / stepSize).toInt()
        this.value = (value.toDouble() / stepSize).toInt()

        // NOTE: workaround for a bug that rendered the selected value wrong until user scrolled, see also: https://stackoverflow.com/q/27343772/3451975
        (NumberPicker::class.java.getDeclaredField("mInputText").apply { isAccessible = true }.get(this) as EditText).filters = emptyArray()
    }

    MaterialAlertDialogBuilder(context)
        .setTitle(title)
        .setView(numberPicker)
        .setPositiveButton("OK") { _, _ -> valueChooseAction(numberPicker.value.toDouble() * stepSize) }
        .setNeutralButton("Cancel") { _, _ -> /* do nothing, closes dialog automatically */ }
        .show()
}

Now you can use it like this (in a Fragment):

showNumberPickerDialog(
    title = "Your Weight",
    value = 75.0, // in kilogramsrange = 10.0 .. 300.0,
    stepSize = 0.1,
    formatToString = { "$it kg" },
    valueChooseAction = { saveNewWeight(it) }
)

Post a Comment for "Android Numberpicker For Floating Point Numbers"