具有不可编辑/不可取消后缀的EditText

时间:2015-02-24 18:40:47

标签: android parsing android-edittext fixed

我为我的一个活动创建了一个布局,用户可以在某些EditText小部件中插入一个值。我需要这些EditText中的一些必须具有必须不可编辑的后缀(如cm,mm等)。 在用户插入值之后,我将解析这些EditText的内容,避免使用后缀,因此我将处理没有后缀的唯一输入。怎么做?

我已经在这里搜索过并搜索过,但没有任何帮助。 我发现像https://stackoverflow.com/a/20794581/2516399这样的答案对我没有帮助。

我希望我的问题很明确......对不起我的英语

7 个答案:

答案 0 :(得分:9)

这是我的解决方案:一个EditText类,用于绘制文本后面的后缀。有两个自定义属性用于定义后缀的文本和后缀填充(在EditText的左下角)。

public class EditTextWithSuffix extends EditText {
    TextPaint textPaint = new TextPaint();
    private String suffix = "";
    private float suffixPadding;

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

    public EditTextWithSuffix(Context context, AttributeSet attrs) {
        super(context, attrs);
        getAttributes(context, attrs, 0);
    }

    public EditTextWithSuffix(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getAttributes(context, attrs, defStyleAttr);
    }

    @Override
    public void onDraw(Canvas c){
        super.onDraw(c);
        int suffixXPosition = (int) textPaint.measureText(getText().toString()) + getPaddingLeft();
        c.drawText(suffix, Math.max(suffixXPosition, suffixPadding), getBaseline(), textPaint);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        textPaint.setColor(getCurrentTextColor());
        textPaint.setTextSize(getTextSize());
        textPaint.setTextAlign(Paint.Align.LEFT);
    }

    private void getAttributes(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.EditTextWithSuffix, defStyleAttr, 0);
        if(a != null) {
            suffix = a.getString(R.styleable.EditTextWithSuffix_suffix);
            if(suffix == null) {
                suffix = "";
            }
            suffixPadding = a.getDimension(R.styleable.EditTextWithSuffix_suffixPadding, 0);
        }
        a.recycle();
    }
}

这是属性定义:

<resources>
    <declare-styleable name="EditTextWithSuffix">
        <attr name="suffix" format="string|reference" />
        <attr name="suffixPadding" format="dimension" />
    </declare-styleable>
</resources>

答案 1 :(得分:4)

试试这个

final EditText eTxt = (EditText) findViewById(R.id.edit_text);

eTxt.setText("cm");
Selection.setSelection(eTxt.getText(), eTxt.getText().length());

eTxt.addTextChangedListener(new TextWatcher() {

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // TODO Auto-generated method stub

    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterTextChanged(Editable s) {
        if(!s.toString().startsWith("cm")){
            eTxt.setText("cm");
            Selection.setSelection(eTxt.getText(), eTxt.getText().length());
        }

    }
});

答案 2 :(得分:3)

private static final String mSuffix = "SUFX";

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        final EditText et = new EditText(this);
        et.setText(mSuffix);

        et.setOnFocusChangeListener(new OnFocusChangeListener() {   
            @Override
            public void onFocusChange(View v, boolean hasFocus) {

                //NO FOCUS
                if(!hasFocus){
                    //HAS USER CLEARED THE SUFFIX
                    if(!et.getText().toString().contains(mSuffix)){
                        //ADDING SUFFIX AGAIN
                        String newText = et.getText().toString();
                        et.setText(mSuffix+newText);
                    }
                }
            }
        });


    }

在我看来,使用Regular Exp。检查后缀。它会更安全,更简单。

<强>解:2

这是另一种解决方案,有些棘手;)

   <RelativeLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/test_value"
            android:layout_alignParentLeft="true"
            android:id="@+id/editText2"
            android:layout_gravity="center"
            />
    <TextView
            android:id="@+id/text_hint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:text="@string/hint_test"
            android:textSize="18sp"
            android:layout_marginRight="10dp"
            android:textColor="#808080"
            />
</RelativeLayout>

<强> RESULT / OUTPUT

OUTPUT:

REF:计算器

答案 3 :(得分:1)

我为EditText做了扩展功能:

fun EditText.addSuffix(suffix: String) {
    val editText = this
    val formattedSuffix = " $suffix"
    var text = ""
    var isSuffixModified = false

    val setCursorPosition: () -> Unit =
        { Selection.setSelection(editableText, editableText.length - formattedSuffix.length) }

    val setEditText: () -> Unit = {
        editText.setText(text)
        setCursorPosition()
    }

    this.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(editable: Editable?) {
            val newText = editable.toString()

            if (isSuffixModified) {
                // user tried to modify suffix
                isSuffixModified = false
                setEditText()
            } else if (text.isNotEmpty() && newText.length < text.length && !newText.contains(formattedSuffix)) {
                // user tried to delete suffix
                setEditText()
            } else if (!newText.contains(formattedSuffix)) {
                // new input, add suffix
                text = "$newText$formattedSuffix"
                setEditText()
            } else {
                text = newText
            }
        }

        override fun beforeTextChanged(charSequence: CharSequence?, start: Int, count: Int, after: Int) {
            charSequence?.let {
                val textLengthWithoutSuffix = it.length - formattedSuffix.length
                if (it.isNotEmpty() && start > textLengthWithoutSuffix) {
                    isSuffixModified = true
                }
            }
        }

        override fun onTextChanged(charSequence: CharSequence?, start: Int, before: Int, count: Int) {
        }
    })
}

然后您可以将其用作:

yourEditTextView.addSuffix("suffix")

答案 4 :(得分:0)

对于带字母后缀的数字edittext,请尝试以下代码:-

expiry.addTextChangedListener(new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // TODO Auto-generated method stub

    }

    @Override
    public void beforeTextChanged(CharSequence c, int start, int count,
                                  int after) {
        // TODO Auto-generated method stub

    }

    @Override
    public void afterTextChanged(Editable e) {
        String s = e.toString();
        if (s.length() > 0) {
            if (!s.endsWith("days")) {
                if (!s.equals(s + "days")) {
                    s = s.replaceAll("[^\\d.]", "");
                    expiry.setText(s + "days");
                } else {
                    expiry.setSelection(s.length() - "days".length());
                }
            } else {
                expiry.setSelection(s.length() - "days".length());
                if (s.equals("days")) {
                    expiry.setText("");
                }
            }
        }
    }
});

答案 5 :(得分:0)

对于任何与Kotlin合作的人:

class EditTextWithSuffix: EditText {
    private val textPaint = TextPaint()
    private var suffix:String = ""
    private var suffixPadding:Float = 0f

    constructor(context: Context): super(context)

    constructor(context: Context, attrs: AttributeSet): super(context, attrs){
        getAttributes(context, attrs)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //I do this check so that the suffix is not drawn on top of the hint if any
        if(this.text.isNotEmpty()) {
            //Get the position that the suffix should be
            val suffixXPosition = textPaint.measureText(this.text.toString()) + paddingLeft + suffixPadding

            //Draw the suffix in the view
            canvas?.drawText(
                suffix,
                max(suffixXPosition, suffixPadding),
                baseline.toFloat(),
                textPaint
            )
        }
    }

    /**
     * Sets the properties of the textPaint to the same as
     * the EditText view
     */
    override fun onFinishInflate() {
        super.onFinishInflate()
        textPaint.color = currentTextColor
        textPaint.textSize = textSize
        textPaint.textAlign = Paint.Align.LEFT
    }

    /**
     * Retrieves the attributes from the layout file
     */
    private fun getAttributes(context: Context, attrs: AttributeSet){
        val typedArray: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.EditTextWithSuffix, 0, 0)

        //Get the suffix attribute
        val theSuffix = typedArray.getString(R.styleable.EditTextWithSuffix_suffix)
        theSuffix?.let {
            suffix = it
        }

        //Get the padding attribute
        suffixPadding = typedArray.getDimension(R.styleable.EditTextWithSuffix_suffixPadding, 0f)

        typedArray.recycle()
    }
}

发件人:https://stackoverflow.com/a/37278154/3971619

答案 6 :(得分:0)

我已经回答了类似的问题here。从1.2.0-alpha01material design library版本开始,文本字段支持前缀和后缀:

<com.google.android.material.textfield.TextInputLayout
        app:prefixText="Price: "
        app:prefixTextAppearance="..."
        app:prefixTextColor="..."
        app:suffixText="Dollar"
        app:suffixTextColor="..."
        app:suffixTextAppearance="...">

    <com.google.android.material.textfield.TextInputEditText .../>

</com.google.android.material.textfield.TextInputLayout>

请注意,后缀固定在文本字段的末尾,并且不随输入文本一起流动。