79

I want to be able to create a Dialog that allows the user to pick a number from a specified range.

I know that there are existing widgets(like those from quietlycoding and the one by SimonVT) that already does this but I'm having hard time integrating those properly into my application. Also, those are primarily widgets. I want something that is very similar to the one in the android developers page tutorials.

I also checked the documentation for the NumberPicker and it said to go check the TimePicker and DatePicker for examples but they only show how to use Time and Date pickers and I'm having a hard time feeling my way around the code and trying to convert the Time Picker to just a normal Number Picker. Does anyone have any idea where to start? I've been looking for solutions for the last 3 hours to no avail.

mmBs
  • 7,728
  • 6
  • 37
  • 43
Razgriz
  • 6,640
  • 12
  • 63
  • 138
  • If you don't need view customization, using `setView()` method of `AlertDialog.Builder` is easier and simpler. [Here](http://stackoverflow.com/questions/11800589/number-picker-dialog) is the sample code. – Lee Han Kyeol Mar 31 '15 at 03:14

5 Answers5

119

I have made a small demo of NumberPicker. This may not be perfect but you can use and modify the same.

public class MainActivity extends Activity implements NumberPicker.OnValueChangeListener
{
    private static TextView tv;
    static Dialog d ;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.textView1);
        Button b = (Button) findViewById(R.id.button11);
         b.setOnClickListener(new OnClickListener()
         {

            @Override
            public void onClick(View v) {
                 show();
            }
            });
           }
     @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {

         Log.i("value is",""+newVal);

     }

    public void show()
    {

         final Dialog d = new Dialog(MainActivity.this);
         d.setTitle("NumberPicker");
         d.setContentView(R.layout.dialog);
         Button b1 = (Button) d.findViewById(R.id.button1);
         Button b2 = (Button) d.findViewById(R.id.button2);
         final NumberPicker np = (NumberPicker) d.findViewById(R.id.numberPicker1);
         np.setMaxValue(100);
         np.setMinValue(0);
         np.setWrapSelectorWheel(false);
         np.setOnValueChangedListener(this);
         b1.setOnClickListener(new OnClickListener()
         {
          @Override
          public void onClick(View v) {
              tv.setText(String.valueOf(np.getValue()));
              d.dismiss();
           }    
          });
         b2.setOnClickListener(new OnClickListener()
         {
          @Override
          public void onClick(View v) {
              d.dismiss();
           }    
          });
       d.show();


    }
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/button11"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:text="Open" />

</RelativeLayout>

dialog.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <NumberPicker
        android:id="@+id/numberPicker1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/numberPicker1"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="98dp"
        android:layout_toRightOf="@+id/numberPicker1"
        android:text="Cancel" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/button2"
        android:layout_alignBottom="@+id/button2"
        android:layout_marginRight="16dp"
        android:layout_toLeftOf="@+id/numberPicker1"
        android:text="Set" />

</RelativeLayout>

Edit:

under res/values/dimens.xml

<resources>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>

</resources>
Raghunandan
  • 129,147
  • 24
  • 216
  • 249
  • It works. I have a question, however, what if I need to let the user pick 2 numbers? Will I be able to assign the second value to a different textView/variable? – Razgriz Jul 23 '13 at 10:11
  • you can use a single picker and set the value to another textview using a boolean true or false. No need for two pickers. And glad the above helped. – Raghunandan Jul 23 '13 at 10:15
  • Also, the padding code over at the xml of the picker does not seem to work. It gives the error `No resource found that matches the given name (at 'paddingBottom' with value @dimen/activity_vertical_margin)` – Razgriz Jul 23 '13 at 10:22
  • @Razgriz those values should be `dimens.xml` . you can create your own. remove those and add your own. i can't post the whole project. – Raghunandan Jul 23 '13 at 10:24
  • @Razgriz check the edit you need to customize your ui on your own you screen size may differ so customize the ui yourself. – Raghunandan Jul 23 '13 at 10:27
  • Okay. Another question. It seems that when the user inputs a value via the keypad, and presses the "Set" button, the value isn't stored properly in the textView. – Razgriz Jul 23 '13 at 10:29
  • @Razgriz another question another thread pls. post it as a new question on stackoverflow with relevant details. answering in comment will lead to long discussion. – Raghunandan Jul 23 '13 at 10:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33968/discussion-between-razgriz-and-raghunandan) – Razgriz Jul 23 '13 at 10:31
  • 4
    NumberPicker is min 11 api. What about lower api levels ? – alicanbatur Nov 20 '13 at 08:31
  • Android requires the OK button to be on the right. It actually reverses the listeners otherwise. – sbaechler May 18 '14 at 15:22
  • @sbaechler this answer is posted long ago. So its a custom dialog and you ca customize how you want. – Raghunandan May 18 '14 at 15:24
  • In case someone else is looking for a more in-depth explanation of chains and the possible values: here's the [official documentation](https://developer.android.com/training/constraint-layout/index.html#constrain-chain) – Griddo Jul 01 '17 at 16:19
21

To show NumberPicker in AlertDialog use this code :

final AlertDialog.Builder d = new AlertDialog.Builder(context);
LayoutInflater inflater = this.getLayoutInflater();
View dialogView = inflater.inflate(R.layout.number_picker_dialog, null);
d.setTitle("Title");
d.setMessage("Message");
d.setView(dialogView);
final NumberPicker numberPicker = (NumberPicker) dialogView.findViewById(R.id.dialog_number_picker);
numberPicker.setMaxValue(50);
numberPicker.setMinValue(1);
numberPicker.setWrapSelectorWheel(false);
numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
    @Override
    public void onValueChange(NumberPicker numberPicker, int i, int i1) {
        Log.d(TAG, "onValueChange: ");
    }
});
d.setPositiveButton("Done", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
        Log.d(TAG, "onClick: " + numberPicker.getValue());
    }
});
d.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialogInterface, int i) {
    }
});
AlertDialog alertDialog = d.create();
alertDialog.show();

number_picker_dialog.xml

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center_horizontal">

<NumberPicker
    android:id="@+id/dialog_number_picker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
</LinearLayout>
Morgoth
  • 4,139
  • 5
  • 35
  • 53
Kapil Rajput
  • 10,723
  • 7
  • 40
  • 59
9

Consider using a Spinner instead of a Number Picker in a Dialog. It's not exactly what was asked for, but it's much easier to implement, more contextual UI design, and should fulfill most use cases. The equivalent code for a Spinner is:

Spinner picker = new Spinner(this);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, yourStringList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
picker.setAdapter(adapter);
GLee
  • 4,680
  • 4
  • 31
  • 35
7

For kotlin lovers.

fun numberPickerCustom() {
    val d = AlertDialog.Builder(context)
    val inflater = this.layoutInflater
    val dialogView = inflater.inflate(R.layout.number_picker_dialog, null)
    d.setTitle("Title")
    d.setMessage("Message")
    d.setView(dialogView)
    val numberPicker = dialogView.findViewById<NumberPicker>(R.id.dialog_number_picker)
    numberPicker.maxValue = 15
    numberPicker.minValue = 1
    numberPicker.wrapSelectorWheel = false
    numberPicker.setOnValueChangedListener { numberPicker, i, i1 -> println("onValueChange: ") }
    d.setPositiveButton("Done") { dialogInterface, i ->
        println("onClick: " + numberPicker.value)       
        }
    d.setNegativeButton("Cancel") { dialogInterface, i -> }
    val alertDialog = d.create()
    alertDialog.show()
}

and number_picker_dialog.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal">

    <NumberPicker
        android:id="@+id/dialog_number_picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>
FariborZ
  • 359
  • 7
  • 15
Bozzo
  • 289
  • 1
  • 3
  • 13
6

A Simple Example:

layout/billing_day_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <NumberPicker
        android:id="@+id/number_picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" />

    <Button
        android:id="@+id/apply_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/number_picker"
        android:text="Apply" />

</RelativeLayout>

NumberPickerActivity.java

import android.app.Activity;

import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.NumberPicker;

public class NumberPickerActivity extends Activity 
{

  @Override
  protected void onCreate(Bundle savedInstanceState) 
  {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.billing_day_dialog);
    NumberPicker np = (NumberPicker)findViewById(R.id.number_picker);
    np.setMinValue(1);// restricted number to minimum value i.e 1
    np.setMaxValue(31);// restricked number to maximum value i.e. 31
    np.setWrapSelectorWheel(true); 

    np.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() 
    {

      @Override
      public void onValueChange(NumberPicker picker, int oldVal, int newVal) 
      {

       // TODO Auto-generated method stub

       String Old = "Old Value : ";

       String New = "New Value : ";

      }
    });

     Log.d("NumberPicker", "NumberPicker");

   }

}/* NumberPickerActivity */

AndroidManifest.xml : Specify theme for the activity as dialogue theme.

<activity
  android:name="org.npn.analytics.call.NumberPickerActivity"
  android:theme="@android:style/Theme.Holo.Dialog"
  android:label="@string/title_activity_number_picker" >
</activity>

Hope it will help.

NEERAJ SWARNKAR
  • 368
  • 3
  • 9