我为我的一个活动创建了一个布局,用户可以在某些EditText小部件中插入一个值。我需要这些EditText中的一些必须具有必须不可编辑的后缀(如cm,mm等)。 在用户插入值之后,我将解析这些EditText的内容,避免使用后缀,因此我将处理没有后缀的唯一输入。怎么做?
我已经在这里搜索过并搜索过,但没有任何帮助。 我发现像https://stackoverflow.com/a/20794581/2516399这样的答案对我没有帮助。
我希望我的问题很明确......对不起我的英语
答案 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 强>
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()
}
}
答案 6 :(得分:0)
我已经回答了类似的问题here。从1.2.0-alpha01的material 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>
请注意,后缀固定在文本字段的末尾,并且不随输入文本一起流动。