Tôi cũng đã đấu tranh trong một thời gian khá dài, nhưng cuối cùng tôi đã tìm ra giải pháp!
Chỉ cần tạo một lớp EditText tùy chỉnh như sau:
public class EditTextImeMultiline extends EditText {
public void init() {
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) {
for (int i = s.length(); i > 0; i--)
if (s.subSequence(i - 1, i).toString().equals("\n"))
s.replace(i - 1, i, "");
}
});
setSingleLine();
setHorizontallyScrolling(false);
this.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
EditTextImeMultiline.this.setLines(EditTextImeMultiline.this.getLineCount());
}
});
}
public EditTextImeMultiline(Context context) {
super(context);
init();
}
public EditTextImeMultiline(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public EditTextImeMultiline(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
}
Lớp này loại bỏ lineBreaks (\ n), bao bọc văn bản như textMultiline sẽ làm, VÀ cho phép bạn thay thế nút Enter bằng một ImeAction;).
Bạn chỉ cần gọi nó trong XML của mình thay vì lớp EditText cổ điển.
Để giải thích logic ở đây:
- Đặt EditText dưới dạng singleLine để có thể hiển thị nút ImeAction thay vì Enter.
- Loại bỏ cuộn ngang để làm cho văn bản chuyển sang dòng tiếp theo khi đến cuối dạng xem.
- Xem các thay đổi về bố cục với onGlobalLayoutListener và đặt tham số "dòng" thành "số dòng" của văn bản hiện tại được giữ bởi editText. Đây là những gì làm mới chiều cao của nó.