0

我想创建一个带有显示值数组的 NumberPicker。当显示 NumberPicker 时,这些值不应更改,但最小值和最大值会根据用户操作动态更改。

这是代码:

<?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/picker"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"/>
</RelativeLayout>

在主要活动中

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final String[] values = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};

        NumberPicker picker = (NumberPicker) findViewById(R.id.picker);
        picker.setDisplayedValues(values);
        picker.setMaxValue(7);
        picker.setMinValue(3);

        picker.setWrapSelectorWheel(false);
    }
}

当我设置最大值而不设置最小值时,我会以“0”和“7”(包括)之间的显示值结束。如果我将 minValue 设置为 0 我有相同的行为。但是,如果我将 minValue 设置为 3,我会以“0”和“4”之间的显示值结束。当它应该在“3”和“7”之间时。

我不明白为什么。我做错了什么还是组件有问题?

4

3 回答 3

3

如果您查看 setMinValue 或 setMaxValue 的实现,则会有一条评论说:

 * <strong>Note:</strong> The length of the displayed values array
 * set via {@link #setDisplayedValues(String[])} must be equal to the
 * range of selectable numbers which is equal to
 * {@link #getMaxValue()} - {@link #getMinValue()} + 1.

因此,要解决此问题,最好在要更新显示的值时设置值列表。

//do this once in onCreate and save the values list somewhere where you have access
final List<String> values = new ArrayList<>();
for (int i = 0; i < 10; ++i) {
    values.add(String.valueOf(i));
}
NumberPicker picker = (NumberPicker) findViewById(R.id.picker);
picker.setWrapSelectorWheel(false);


//do this every time you want to change the displayed values and set minValue and maxValue accordingly
//also make sure that you stay within the bounds of value
int minValue = 3;
int maxValue = 7;

final List<String> subValues = values.subList(minValue, maxValue + 1);
String[] subValuesArray = new String[subValues.size()];
subValuesArray = subValues.toArray(subValuesArray);
picker.setDisplayedValues(subValuesArray);
picker.setMinValue(0);
picker.setMaxValue(subValues.size() - 1);
于 2017-02-23T12:34:43.067 回答
1

为简洁起见@Bmuig 答案,只是一个辅助函数:

private void configurePicker(NumberPicker picker, ArrayList<String> values, int minValue, int maxValue, int currentValue) {
    picker.setDisplayedValues(values) //to avoid out of bounds
    picker.setMinValue(minValue);
    picker.setMaxValue(maxValue);
    picker.setValue(currentValue);
    picker.setDisplayedValues((String[]) values.subList(minValue, maxValue + 1).toArray());
}
于 2017-07-07T04:08:09.590 回答
1

It is explainable from the documentation.

When you set min and max, you define int values that can be entered with NumberPicker. So setValue(int) only accepts values from min to max.

The displayValues() is labels override. And it will be used in a next manner - NumberPicker will take label with index value - min.

于 2017-02-23T12:14:54.387 回答