【问题标题】:Set unchangeable some part of editText android设置不可更改的editText android的某些部分
【发布时间】:2013-11-16 06:59:36
【问题描述】:

我有一些用于手机号码输入的 EditText。应用程序必须为每个国家/地区添加独特的文字。例如亚美尼亚必须添加+374,用户必须填写其他数字。另外+374 必须是不可更改的,用户不能更改或删除它。那么有什么方法可以做到这一点吗?

编辑:

我不想将 textView 或其他视图与此文本一起使用,并将其放在 ediText 的左侧。我想找到一些操作较少的方法。我需要冻结文本而不是检查每个文本更改或在用户删除其中的某些部分时添加丢失的文本。

【问题讨论】:

  • 最简单的方法——一个文本视图显示“+374”,一个编辑文本显示第二部分。你也可以使用单个editText,但应该实现TextWatcher
  • 感谢回复,我不想用textView,还有关于textWatcher我想找一些操作少的方法。当用户删除其中的某些部分时,我需要冻结文本而不是检查每个文本更改或添加丢失的文本。
  • 您可以捕获文本事件并在输入第一个数字时连接文本的静态部分。或者你可以用 fouch gain 来测试同样的东西。只是和想法不确定。

标签: android android-edittext


【解决方案1】:

使用文本观察器,当用户输入 +3 时,它会以 +374 完成,它会比较前四个字符,如果相同,则禁用软键盘的后按,这样它就不会更改文本并输入另一个数字追加从 textwatcher 中使用的文本

【讨论】:

  • 感谢您的回复。这是一个好主意,但我认为它有一些错误。我有 +374,然后我输入 "5" ,所以我有 "+374 5 " 然后我可以从头开始添加 "b",所以我将有 "b+374 5"
  • 你必须在 5 之后添加 b 然后它不会显示任何错误..先使用 textwatcher 然后添加数字
【解决方案2】:
public class MainActivity extends Activity {

private EditText editText;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    editText = (EditText) findViewById(R.id.editText1);
    editText.setText("+374");
    Selection.setSelection(editText.getText(), editText.getText().length());
    editText.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("+374")) {
                editText.setText("+374");
                Selection.setSelection(editText.getText(), editText
                        .getText().length());

            }

        }

    });
}

}

【讨论】:

  • 感谢您的回复和代码,但我想我可以输入“5”,所以我会得到这个“5+374”文本。我没有找到任何会禁止用户进行此更改的内容
  • 对不起,现在我的答案做了改变
  • 现在您可以限制用户输入任何内容,而无需以固定文本开头
  • 感谢您的回答,感谢您花时间在上面。但是在对我的问题发表评论后,我在问题中添加了编辑字段,所以你的答案不是我想要的正确答案,但是非常感谢你,我赞成你的问题,但不能接受。跨度>
  • 我不会花时间来获得选票,但我想了解更多信息,为什么我要花一些时间...你能告诉我我的答案有什么问题,以便我改进
【解决方案3】:

创建一个自定义的可绘制类,这将有助于将文本转换为可绘制对象。

public class TextDrawable extends Drawable {

  private final String text;
  private final Paint paint;

  public TextDrawable(String text) {
      this.text = text;
      this.paint = new Paint();
      paint.setColor(Color.BLACK);
      paint.setTextSize(16f);
      paint.setAntiAlias(true);
      paint.setTextAlign(Paint.Align.LEFT);
  }

  @Override
  public void draw(Canvas canvas) {
      canvas.drawText(text, 0, 6, paint);
  }

  @Override
  public void setAlpha(int alpha) {
      paint.setAlpha(alpha);
  }

  @Override
  public void setColorFilter(ColorFilter cf) {
      paint.setColorFilter(cf);
  }

  @Override
  public int getOpacity() {
      return PixelFormat.TRANSLUCENT;
  }
}

然后将edittext左侧的drawable设置为

EditText et = (EditText)findViewById(R.id.editText1);
String code = "+374";
et.setCompoundDrawablesWithIntrinsicBounds(new TextDrawable(code), null, null, null);
et.setCompoundDrawablePadding(code.length()*10);

其中edittext在布局文件中定义为

<EditText
android:id="@+id/editText1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:ems="10" >
  <requestFocus />
</EditText>

最终输出的样子

【讨论】:

  • 如何在EditText的右侧添加drawable?
  • 在xml文件中使用android:drawableRight
  • 有可能有这样的东西吗? i.imgur.com/VVq3jId.png 我想将 .jpg 扩展为不可编辑,并且始终停留在用户输入/编辑的文本的右侧。一直在努力使它工作无济于事..
  • 在您的情况下,您可以实现 TextWatcher 在末尾附加 .jpg,因为文件名的长度可能因您的情况而异。
  • 这似乎不再起作用,文本不符合 EditText 的文本大小。当您更改类文件中的大小以及填充时,它可以工作,但是添加的文本与输入的文本不对齐。
【解决方案4】:

您可以创建类扩展 AppCompatEditText 或 EditText。

public class CEditTextMaster extends AppCompatEditText {

        private boolean isNeedNoChangeSomeCharacters;
        private String charactersNoChange;

        public CEditTextMaster(Context context) {
            super(context);
            init(context, null);
        }

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

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

        public void init(Context context, @Nullable AttributeSet attrs) {

            if (isInEditMode())
                return;

            addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (isNeedNoChangeSomeCharacters && charactersNoChange != null) {
                        if (!getText().toString().startsWith(charactersNoChange)) {
                            removeTextChangedListener(this);
                            if (charactersNoChange.length() > s.length()) {
                                setText(charactersNoChange);
                            } else {
                                setText(charactersNoChange + getText());
                            }
                            setSelection(getText().toString().length());
                            addTextChangedListener(this);
                        }
                    }
                }
            });

        }

        @Override
        protected void onSelectionChanged(int selStart, int selEnd) {
            if (isNeedNoChangeSomeCharacters && charactersNoChange != null) {
                if (length() > charactersNoChange.length() && selStart < charactersNoChange.length()) {
                    setSelection(charactersNoChange.length(),selEnd);
                }
            }
        }


        @Override
        public void setText(CharSequence text, BufferType type) {
            super.setText(text, type);
            if (isNeedNoChangeSomeCharacters && charactersNoChange != null) {
                if (!getText().toString().trim().startsWith(charactersNoChange)) {
                    setText(charactersNoChange + getText());
                }
            }
        }

        public void setCharactersNoChangeInitial(String charactersNoChange) {
            isNeedNoChangeSomeCharacters = true;
            this.charactersNoChange = charactersNoChange;
            if (!getText().toString().trim().startsWith(charactersNoChange)) {
                setText(getText());
            }
        }

}

使用:

edt.setCharactersNoChangeInitial("+734 ");

【讨论】:

    【解决方案5】:

    我选择了一个解决方案,类似于另一个提交的解决方案,扩展 EditText 并修改 onSelectionChanged。这甚至可以防止用户进入该区域。

    这是我正在使用的:

    import android.content.Context
    import android.text.Editable
    import android.util.AttributeSet
    import androidx.appcompat.widget.AppCompatEditText
    
    class PrefixEditText(context: Context, attrs: AttributeSet?) : AppCompatEditText(context, attrs) {
        private var prefix: String? = null
    
        fun setPrefix(prefix: String) {
            this.prefix = prefix
            setText(prefix)
    
            addTextChangedListener(object : TextWatcher {
                override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit
                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) = Unit
    
                override fun afterTextChanged(s: Editable?) {
                    // Block deleting the prefix
                    if (s?.startsWith(prefix) == false) {
                        setText(prefix)
                    }
                }
            })
        }
    
        override fun onSelectionChanged(selStart: Int, selEnd: Int) {
            var newStart = selStart
            var newEnd = selEnd
            prefix?.length?.let {
                newStart = if (selStart < it) it else selStart
                newEnd = if (selEnd < it) it else selEnd
            }
    
            if (selStart != newStart || selEnd != newEnd) {
                setSelection(newStart, newEnd)
            } else {
                super.onSelectionChanged(selStart, selEnd)
            }
        }
    
        // Here to conform to EditText's API
        // Could also just override getText()
        fun getPostText(): Editable? {
            return prefix?.let {
                Editable.Factory.getInstance().newEditable(text)?.delete(0, it.length)
            } ?: run {
                text
            }
        }
    
        // Here for convenience, to avoid instantiating a new Editable, if the text is all you need
        fun getPostCharSeq(): CharSequence? {
            return prefix?.let {
                text?.substring(it.length)
            } ?: run {
                text
            }
        }
    }
    

    通过测试:

    import android.view.ViewGroup
    import android.widget.FrameLayout
    import androidx.test.ext.junit.runners.AndroidJUnit4
    import androidx.test.rule.ActivityTestRule
    import com.roosterteeth.roosterteeth.TestActivity
    import org.junit.Assert
    import org.junit.Rule
    import org.junit.Test
    import org.junit.runner.RunWith
    
    @RunWith(AndroidJUnit4::class)
    class PrefixEditTextTest {
        @Rule
        @JvmField
        var activityRule: ActivityTestRule<TestActivity> = ActivityTestRule(TestActivity::class.java, true, true)
    
        private fun setupView(prefix: String, message: String): PrefixEditText {
            val editText = PrefixEditText(activityRule.activity, null)
            val lp = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
            activityRule.activity.addContentView(editText, lp)
    
            editText.setPrefix(prefix)
            editText.append(message)
    
            return editText
        }
    
        @Test
        fun testSelection() {
            activityRule.runOnUiThread {
                val prefix = "pre: "
                val message = "hello world"
                val editText = setupView(prefix, message)
    
                editText.setSelection(0)
                Assert.assertEquals(editText.selectionStart, prefix.length)
                Assert.assertEquals(editText.selectionEnd, prefix.length)
                editText.setSelection(0, editText.length())
                Assert.assertEquals(editText.selectionStart, prefix.length)
                Assert.assertEquals(editText.selectionEnd, editText.length())
            }
        }
    
        @Test
        fun testGetPostText() {
            activityRule.runOnUiThread {
                val prefix = "pre: "
                val message = "hello world"
                val editText = setupView(prefix, message)
    
                Assert.assertEquals(message, editText.getPostText().toString())
                // This test is after to make sure that getting the post text did not actually modify the contents
                Assert.assertEquals("pre: $message", editText.text.toString())
            }
        }
    
        @Test
        fun testGetPostCharSeq() {
            activityRule.runOnUiThread {
                val prefix = "pre: "
                val message = "hello world"
                val editText = setupView(prefix, message)
    
                Assert.assertEquals(message, editText.getPostCharSeq())
                // This test is after to make sure that getting the post text did not actually modify the contents
                Assert.assertEquals("pre: $message", editText.text.toString())
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      相关资源
      最近更新 更多