2012-10-19 46 views

Trả lời

7

Tại sao không chỉ cần thêm một cái gì đó OnValueChangeListener như:

numberPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { 

    @Override 
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 
     picker.setValue((newVal < oldVal)?oldVal-5:oldVal+5); 
    } 

}); 
+0

Ok, nhưng điều đó cũng giống như sử dụng onScrollListener. Sử dụng sự kiện là cách duy nhất để thực hiện hiệu ứng này? – user940016

+0

Có, tôi cho rằng bạn có thể mở rộng lớp để có kích thước bước và sau đó ghi đè phương thức onClick. Đó có lẽ là nhiều mã hơn là chỉ sử dụng người nghe mặc dù. – ajpolt

+0

Phương pháp nghe phải là onValueChange thay vì onChange và setter nên được setOnValueChangedListener ngay bây giờ. – Loolooii

25

Các NumberPicker trong Android có một phương pháp gọi là setDisplayedValues. Bạn có thể sử dụng giá trị này để hiển thị các giá trị tùy chỉnh (cần có một chuỗi các chuỗi) và sau đó ánh xạ chúng khi bạn cần giá trị. Vì vậy, nếu bạn cần bước 5 trong một bảng chọn phút, ví dụ, bạn có thể tạo một mảng như thế này:

String[] minuteValues = new String[12]; 

for (int i = 0; i < minuteValues.length; i++) { 
    String number = Integer.toString(i*5); 
    minuteValues[i] = number.length() < 2 ? "0" + number : number; 
} 

minutePicker.setDisplayedValues(minuteValues); 

Và sau đó khi bạn nhận được giá trị trong OnValueChangeListener, bạn chỉ cần bỏ nó trở lại một số nguyên:

Integer.parseInt(minuteValues[newVal]); 
5

Các NumberPicker trong Android có một phương pháp gọi là setDisplayedValues. Bạn có thể sử dụng cái này để hiển thị các giá trị tùy chỉnh (nó lấy một mảng Strings) và sau đó ánh xạ chúng khi bạn cần giá trị.

Ví dụ, bạn có thể tạo một hàm như thế này:

public String[] getArrayWithSteps (int iMinValue, int iMaxValue int iStep) 
{ 
    int iStepsArray = (iMaxValue-iMinValue)/iStep+1; //get the lenght array that will return 

    String[] arrayValues= new String[iStepsArray]; //Create array with length of iStepsArray 

    for(int i = 0; i < iStepsArray; i++) 
    { 
    arrayValues[i] = String.valueOf(iMinValue + (i*iStep)); 
    } 

    return arrayValues; 
} 

Vì vậy, bạn nên gọi phương thức>NumberPicker.setDisplayedValues, ví dụ:

int min = 5; 
int max = 180; 
int step = 10; 

String[] myValues = getArrayWithSteps(min, max, step); //get the values with steps... Normally 

//Setting the NumberPick (myNumberPick) 
myNumberPick.setMinValue(0); 
myNumberPick.setMaxValue((max-step)/min+1); //Like iStepsArray in the function 
//Because the Min and Max Value should be the range that will show. 
//For example, Min = 0 and Max = 2, so the NumberPick will display the first three strings in the array String (myValues); 
myNumberPick.setDisplayedValues(myValues);//put on NumberPicker 

Đối với có được giá trị gia tăng trong NumberPick:

String sValue = String.valueOf(10+(myNumberPick.getValue()*5)); //->> (iMinValue + (myNumberPick.getValue()*iStep)) 

Xin lỗi my eng lish ...

+0

myNumberPick.setMaxValue ((max-step)/min + 1); // Giống như iStepsArray trong hàm Sẽ tốt hơn nếu là: (max-min)/bước. - Min có thể bằng 0 và chia cho 0 nó sai. - không có +1 vì bạn sẽ thêm 1 giá trị – Sigvent

8

Để thiết lập một số bước của '5' ví dụ, sử dụng NumberPicker.Formatter:

NumberPicker.Formatter formatter = new NumberPicker.Formatter() { 
     @Override 
     public String format(int value) { 
      int temp = value * 5; 
      return "" + temp; 
     } 
    }; 
    numberPicker.setFormatter(formatter); 
+0

thực sự, giải pháp này đơn giản nhưng phức tạp, tôi có thể thích cách này – khalifavi

+0

Đừng quên vẫn đặt numberPicker.setMaxValue thành thứ gì đó hợp lý. Nếu bạn không đặt nó ở tất cả các bộ chọn sẽ chỉ hiển thị 0. Đối với một giờ trong gia số 5 phút ví dụ bạn phải đặt nó thành 11, vì bộ chọn sẽ giữ 11 số (0 - 55). – ckn

+0

Cũng nên đặt numberPicker.setDescendantFocusability (ViewGroup.FOCUS_BLOCK_DESCENDANTS); Nếu không, trường số trong bộ chọn sẽ có thể trở thành tiêu điểm cho đầu vào. – ckn

0

Khi sử dụng phương pháp mô tả ở trên, chúng ta cần phải nhận thức được rằng các bảng chọn cho phép người sử dụng không chỉ để chọn một giá trị bằng cách cuộn, nhưng cũng bằng cách nhập nó bằng bàn phím.

Theo mặc định, loại đầu vào của trường nhập được đặt thành TYPE_CLASS_NUMBER và do đó người dùng được trình bày bằng bàn phím số. Có vẻ như khi bạn sử dụng setDisplayedValues công cụ chọn sẽ thay đổi loại thành TYPE_CLASS_TEXT, tuy nhiên, khi bạn sử dụng setFormatter loại đầu vào không thay đổi.

Do đó việc sử dụng trình định dạng trong trường hợp này có thể dẫn đến hành vi không mong muốn. Giả sử bạn muốn người dùng chỉ có thể chọn các giá trị "0" hoặc "5". Bạn có thể có mã như sau:

NumberPicker numberPicker = (NumberPicker) findViewById(R.id.my_number_picker); 
numberPicker.setMinValue(0); 
numberPicker.setMaxValue(1); 
numberPicker.setFormatter(v -> v == 0 ? "0" : "5"); 

Tuy nhiên, trong trường hợp này người dùng được trình bày với bàn phím số nhưng chỉ có thể nhập "0" hoặc "1".

Nếu bạn sử dụng thay vì:

numberPicker.setDisplayedValues(new String[] { "0", "5" }); 

người dùng sẽ thấy bàn phím văn bản, nhưng sẽ có thể nhập "0" hoặc "5" như mong đợi.

Nếu bạn đang bận tâm với bàn phím văn bản, bạn có thể sử dụng phản chiếu để truy cập trường riêng tư và đặt loại đầu vào về số (dĩ nhiên là không được khuyến nghị trừ khi thực sự cần thiết). Trường này được gọi là "mInputText" hoặc "mText" nếu bạn nhắm mục tiêu các oldies goldies như Gingerbread.

try { 
     Field inputField = NumberPicker.class.getDeclaredField("mInputText"); 
     inputField.setAccessible(true); 

     EditText inputText = (EditText) inputField.get(numberPicker); 
     inputText.setRawInputType(InputType.TYPE_CLASS_NUMBER); 
    } catch (ClassCastException e) { 
     // Just ignore this exception and do nothing. 
    } catch (IllegalAccessException e) { 
     // Just ignore this exception and do nothing. 
    } catch (NoSuchFieldException e) { 
     // Just ignore this exception and do nothing. 
    } 
Các vấn đề liên quan