具有增量和准确性的Android Double NumberPicker

时间:2016-04-20 02:37:36

标签: android double formatter numberpicker

我正在尝试使用增量和精度设置为double / float值创建一个修改过的NumberPicker,这样我就可以用1以外的值增加值。对于我的用例,我有一个我想要使用的计算器应用程序2这些NumberPickers中的-3个输入/选择一个double值。一些输入可能在10,000,000的数量级,而其他输入可能很小,如0.0001,所以我需要能够调整增量步长以及每个选择器的精度。由于可能存在非常大范围的值,因此我不想使用setDisplayedValues。我还想让用户直接通过NumberPicker上的EditText输入数字。

这是我到目前为止我的NumberPickerDouble类:

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.text.InputFilter;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.NumberPicker;

import java.math.BigDecimal;

public class NumberPickerDouble extends NumberPicker {
    private double mPrecision = 1;
    private double mIncrement = 1;
    private EditText numberEditText;
    private boolean shouldDisableEditText = true; //set to true to disable edit text input and focus

    public NumberPickerDouble(Context context) {
        super(context);
    }

    public NumberPickerDouble(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }

    public NumberPickerDouble(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public NumberPickerDouble(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(attrs);
    }

    private void init(AttributeSet attrs){
        numberEditText = populateEditText((ViewGroup) this);
        if (numberEditText != null && shouldDisableEditText)
            numberEditText.setFocusable(false);
        processAttributeSet(attrs);
    }

    public void setPrecision(double precision){
        mPrecision = precision;
    }

    public double getPrecision(){
        return mPrecision;
    }

    public void setIncrement(double increment) {
        mIncrement = increment;
        setFormat();
    }

    public double getIncrement(){
        return mIncrement;
    }

    public String getValueFormat(){
        int decimalPlaces = BigDecimal.valueOf(mPrecision).scale();
        if (decimalPlaces > 0)
            return "%." + String.valueOf(decimalPlaces) + "f";
        else
            return "%d";
    }

    public void setDoubleValue(double value){
        setValue((int)(value / mIncrement));
        numberEditText.setFilters(new InputFilter[0]);
    }

    private void setFormat() {
        NumberPicker.Formatter formatter = new NumberPicker.Formatter(){
            @Override
            public String format(int value) {
                double temp = value * mIncrement;
                int precision = BigDecimal.valueOf(mPrecision).scale();
                String newValue;
                if (precision > 0)
                    newValue = String.format("%." + precision +"f", temp);
                else
                    newValue = "" + temp;
                return newValue;

            }
        };
        setFormatter(formatter);
    }

    private EditText populateEditText(ViewGroup viewGroup) {
        int count = viewGroup.getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = viewGroup.getChildAt(i);
            if (child instanceof ViewGroup)
                populateEditText((ViewGroup) child);
            else if (child instanceof EditText)
                return (EditText) child;
        }
        return null;
    }

    private void processAttributeSet(AttributeSet attrs) {

    }
}

增量和精度按预期进行滑动,但我有两个问题:

  1. 首次初始化视图时,NumberPickers不会正确格式化第一个值,它会丢弃小数或者不显示任何内容(请参见下图)。一旦我滚动选择器,它就会消失。我在这个post中尝试了一些建议的解决方案,但似乎没有任何效果。 NumberPicker formatter not working on first rendering

  2. 我无法在NumberPicker的EditText中输入数字,但即使我可以,我也无法弄清楚如何最好地截取输入值,将其除以我在setDoubleValue方法中的增量

  3. 以下是我在上图中设置NumberPickers的方法:

    final NumberPickerDouble np1 = (NumberPickerDouble) v.findViewById(R.id.numPicker1);
    final NumberPickerDouble np2 = (NumberPickerDouble) v.findViewById(R.id.numPicker2);
    final NumberPickerDouble np3 = (NumberPickerDouble) v.findViewById(R.id.numPicker3);
    
    np1.setMaxValue(1000000);
    np2.setMaxValue(200000);
    np3.setMaxValue(200);
    
    np1.setMinValue(0);
    np2.setMinValue(0);
    np3.setMinValue(0);
    
    np1.setPrecision(1);
    np2.setPrecision(1);
    np3.setPrecision(0.001);
    
    np1.setIncrement(100);
    np2.setIncrement(1);
    np3.setIncrement(0.002);
    
    np1.setWrapSelectorWheel(false);
    np2.setWrapSelectorWheel(false);
    np3.setWrapSelectorWheel(false);
    
    np1.setDoubleValue(0);
    np1.setDoubleValue(0);
    np1.setDoubleValue(0);
    

0 个答案:

没有答案