使自定义EditText仅限数字

时间:2017-11-04 09:01:52

标签: android android-edittext custom-controls android-custom-view

我有一个来自here的自定义EditText。

问题:默认情况下,这会打开普通键盘。我想打开数字键盘。我尝试在XML中添加inputType="number",但随后它停止显示占位符行。

如何在显示占位符线的同时打开数字键盘?

enter image description here

另外,如何在课堂内设置maxLength

以下是代码:

public class PinEntryEditText extends android.support.v7.widget.AppCompatEditText {

    public static final String XML_NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android";

    private float mSpace = 10; //24 dp by default, space between the lines
    private float mCharSize;
    private float mNumChars = 6;
    private float mLineSpacing = 8; //8dp by default, height of the text from our lines
    private int mMaxLength = 6;
    private int pinLength;
    private OnClickListener mClickListener;
    private float mLineStroke = 1; //1dp by default
    private float mLineStrokeSelected = 2; //2dp by default
    private Paint mLinesPaint;
    int[][] mStates = new int[][]{
        new int[]{android.R.attr.state_selected}, // selected
        new int[]{android.R.attr.state_focused}, // focused
        new int[]{-android.R.attr.state_focused}, // unfocused
    };

    int[] mColors = new int[]{
        Color.GREEN,
        Color.BLACK,
        Color.GRAY
    };

    ColorStateList mColorStates = new ColorStateList(mStates, mColors);

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

    public PinEntryEditText(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PinEntryEditText , 0, 0);
        try {
            pinLength = ta.getInteger(R.styleable.PinEntryEditText_pinLength , mMaxLength);
        } finally {
            ta.recycle();
        }

        mNumChars = pinLength;
        mMaxLength = pinLength;

        init(context, attrs);
    }

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


    private void init(Context context, AttributeSet attrs) {
        float multi = context.getResources().getDisplayMetrics().density;
        mLineStroke = multi * mLineStroke;
        mLineStrokeSelected = multi * mLineStrokeSelected;
        mLinesPaint = new Paint(getPaint());
        mLinesPaint.setStrokeWidth(mLineStroke);
        if (!isInEditMode()) {
            TypedValue outValue = new TypedValue();

context.getTheme().resolveAttribute(R.attr.colorControlActivated,
                outValue, true);
        final int colorActivated = outValue.data;
        mColors[0] = colorActivated;

        context.getTheme().resolveAttribute(R.attr.colorPrimaryDark,
                outValue, true);
        final int colorDark = outValue.data;
        mColors[1] = colorDark;

        context.getTheme().resolveAttribute(R.attr.colorControlHighlight,
                outValue, true);
        final int colorHighlight = outValue.data;
        mColors[2] = colorHighlight;
    }
    setBackgroundResource(0);
    mSpace = multi * mSpace; //convert to pixels for our density
    mLineSpacing = multi * mLineSpacing; //convert to pixels for our density
    mMaxLength = attrs.getAttributeIntValue(XML_NAMESPACE_ANDROID, "maxLength", mMaxLength);
    mNumChars = mMaxLength;

    //Disable copy paste
    super.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public void onDestroyActionMode(ActionMode mode) {
        }

        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            return false;
        }
    });
    // When tapped, move cursor to end of text.
    super.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            setSelection(getText().length());
            if (mClickListener != null) {
                mClickListener.onClick(v);
            }
        }
    });

}

@Override
public void setOnClickListener(OnClickListener l) {
    mClickListener = l;
}

@Override
public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
    throw new RuntimeException("setCustomSelectionActionModeCallback() not supported.");
}

@Override
protected void onDraw(Canvas canvas) {
    //super.onDraw(canvas);
    int availableWidth = getWidth() - getPaddingRight() - getPaddingLeft();
    if (mSpace < 0) {
        mCharSize = (availableWidth / (mNumChars * 2 - 1));
    } else {
        mCharSize = (availableWidth - (mSpace * (mNumChars - 1))) / mNumChars;
    }

    int startX = getPaddingLeft();
    int bottom = getHeight() - getPaddingBottom();

    //Text Width
    Editable text = getText();
    int textLength = text.length();
    float[] textWidths = new float[textLength];
    getPaint().getTextWidths(getText(), 0, textLength, textWidths);

    for (int i = 0; i < mNumChars; i++) {
        updateColorForLines(i == textLength);
        canvas.drawLine(startX, bottom, startX + mCharSize, bottom, mLinesPaint);

        if (getText().length() > i) {
            float middle = startX + mCharSize / 2;
            canvas.drawText(text, i, i + 1, middle - textWidths[0] / 2, bottom - mLineSpacing, getPaint());
        }

        if (mSpace < 0) {
            startX += mCharSize * 2;
        } else {
            startX += mCharSize + mSpace;
        }
    }
}


private int getColorForState(int... states) {
    return mColorStates.getColorForState(states, Color.GRAY);
}

/**
 * @param next Is the current char the next character to be input?
 */
private void updateColorForLines(boolean next) {
    if (isFocused()) {
        mLinesPaint.setStrokeWidth(mLineStrokeSelected);
        mLinesPaint.setColor(getColorForState(android.R.attr.state_focused));
        if (next) {
            mLinesPaint.setColor(getColorForState(android.R.attr.state_selected));
        }
    } else {
        mLinesPaint.setStrokeWidth(mLineStroke);
        mLinesPaint.setColor(getColorForState(-android.R.attr.state_focused));
    }
}

}

XML:

<com.mridulahuja.kudamm.tools.PinEntryEditText
        android:id="@+id/txtToken"
        android:layout_width="0dp"
        android:layout_height="55dp"
        android:ems="10"
        pin:pinLength="6"
        android:gravity="center"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginRight="15dp"
        android:layout_marginEnd="15dp"
        android:layout_marginLeft="15dp"
        android:layout_marginStart="15dp"
        app:layout_constraintLeft_toLeftOf="parent"/>

1 个答案:

答案 0 :(得分:0)

默认长度由代码设置:

private int mMaxLength = 6;

但是这个库也从xml读取值:

mMaxLength = attrs.getAttributeIntValue(XML_NAMESPACE_ANDROID, "maxLength", mMaxLength);

所以你可以使用这两种方法。

为了使占位符可见,您应该像这样添加_符号:

android:digits="0123456789_"

根据您的需要,您可能需要添加其他符号。