Multiline EditText với Hoàn tất nhãn hành động SoftInput trên 2.3


82

Có cách nào để hiển thị Nhiều dòng EditTextvà sử dụng Nhãn hành động IME "Xong" trên Android 2.3 không?

Trong Android 2.2, đây không phải là vấn đề, nút enter hiển thị Nhãn hành động IME "Xong" ( android:imeActionLabel="actionDone") và loại bỏ Nhập liệu mềm khi được nhấp.

Khi định cấu hình EditTextcho nhiều dòng, Android 2.3 sẽ loại bỏ khả năng hiển thị hành động "Xong" đối với bàn phím Nhập liệu mềm.

Tôi đã quản lý để thay đổi hoạt động của nút nhập Soft Input bằng cách sử dụng a KeyListener, tuy nhiên nút enter vẫn trông giống như phím enter.


Đây là tuyên bố của EditText

<EditText
        android:id="@+id/Comment"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="0dp"
        android:lines="3"
        android:maxLines="3"
        android:minLines="3"
        android:maxLength="60"
        android:scrollHorizontally="false"
        android:hint="hint"
        android:gravity="top|left"
        android:textColor="#888"
        android:textSize="14dp"
        />
<!-- android:inputType="text" will kill the multiline on 2.3! -->
<!-- android:imeOptions="actionDone" switches to a "t9" like soft input -->

Khi tôi kiểm tra inputTypegiá trị sau khi tải, cài đặt chế độ xem nội dung trong hoạt động, nó hiển thị là:

inputType = 0x20001

Đó là:

  • lớp học = TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_NORMAL
  • cờ = InputType.TYPE_TEXT_FLAG_MULTI_LINE

Câu trả lời:


163

Chà, sau khi đọc lại TextViewvà các EditorInfotài liệu, rõ ràng là nền tảng sẽ bắt buộc phải có IME_FLAG_NO_ENTER_ACTIONcác chế độ xem văn bản nhiều dòng.

Lưu ý rằng TextViewsẽ tự động đặt cờ này cho bạn trên các chế độ xem văn bản nhiều dòng.

Giải pháp của tôi là phân lớp EditTextvà điều chỉnh các tùy chọn IME sau khi cho phép nền tảng định cấu hình chúng:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    InputConnection connection = super.onCreateInputConnection(outAttrs);
    int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
    if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
        // clear the existing action
        outAttrs.imeOptions ^= imeActions;
        // set the DONE action
        outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
    }
    if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
        outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
    }
    return connection;
}

Ở phần trên, tôi cũng đang ép buộc IME_ACTION_DONE, mặc dù điều đó có thể đạt được thông qua cấu hình bố cục tẻ nhạt.


24
Tôi thường không đưa ra những nhận xét chung chung như 'omg, cảm ơn' nhưng câu trả lời này đủ hữu ích và không được đánh giá cao mà tôi nghĩ rằng nó xứng đáng được công nhận. Tóm lại, omg cảm ơn. :-)
cày

3
+1 cho câu trả lời nhưng nếu bạn đặt loại đầu vào của một văn bản chỉnh sửa từ mã trong trường hợp này. Nó loại bỏ cuộn dọc và thêm cuộn ngang. Để giải quyết vấn đề đó, hãy sử dụng mã bên dưới. editTextObj.setInputType (InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE); Nói chung có thể xảy ra nếu bạn đang sử dụng lại một chế độ xem bằng cách bao gồm các chế độ xem giống nhau trong nhiều bố cục. @ohhorob cảm ơn rất nhiều về giải pháp.
Jayshil Dave

2
Nó hoạt động như một say mê! Nhưng tôi không thực sự hiểu mã. Bạn có một số nơi để tôi có thể đọc về toàn bộ cơ chế cờ?
vanleeuwenbram

Cảm ơn, tôi là người mới bắt đầu, tôi đặt điều này trong hoạt động của mình có sử dụng hộp thoại EditText, vì vậy nó không nằm trong hoạt động xml của tôi. Tôi đã thử đặt mã này trong hoạt động của tôi, nhưng có một lỗi: The method onCreateInputConnection(EditorInfo) of type SMSMain must override or implement a supertype method. Bạn gọi supervào đầu nên không chắc là có vấn đề gì. Bạn có bất kỳ đề xuất? Cảm ơn.
Azurespot

@NoniA. bạn phải tạo lớp con của EditText. và trong lớp đó bạn phải gọi phương thức này. tạo một lớp mở rộng tới EditText. và đặt phương thức đó trong lớp đó.
Shah

103

Câu trả lời của Ohhorob về cơ bản là đúng, nhưng code của anh ấy thực sự là thừa! Về cơ bản nó tương đương với phiên bản đơn giản hơn nhiều này (mã đầy đủ cho người đọc lười biếng):

package com.example.views;

import android.content.Context;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.EditText;

// An EditText that lets you use actions ("Done", "Go", etc.) on multi-line edits.
public class ActionEditText extends EditText
{
    public ActionEditText(Context context)
    {
        super(context);
    }

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

    public ActionEditText(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs)
    {
        InputConnection conn = super.onCreateInputConnection(outAttrs);
        outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        return conn;
    }
}

Lưu ý rằng một số inputTypetùy chọn như textShortMessagelàm cho điều này không hoạt động! Tôi đề nghị bạn bắt đầu với inputType="text". Đây là cách bạn có thể sử dụng nó trong XML của mình.

<com.example.views.ActionEditText
    android:id=...
    android:layout_stuff=...
    android:imeOptions="actionDone"
    android:inputType="textAutoCorrect|textCapSentences|textMultiLine"
    android:maxLines="3" />

Timmmm, cái này đã được thử nghiệm trên 2.3 chưa?
ohhorob

1
Nếu mã của bạn hoạt động trên 2.3, thì mã của tôi cũng vậy. Chúng rất gần giống nhau và tôi dựa trên mã của tôi hoặc của bạn, vì vậy cảm ơn! Có đặc điểm riêng nào của 2.3 không có trong 4.0 không? Tiêu chuẩn "không có hành động nào đối với các chỉnh sửa nhiều dòng" là hành vi có chủ ý do Google thêm vào.
Timmmm

5
Tôi đã thử điều này trên 2.3 (và 4.x) và nó hoạt động cho ứng dụng của tôi.
mlc

2
@ matej.smitala Vâng, bạn không thể có cả hai.
Timmmm 6/12/12

1
Sau nhiều giờ tìm kiếm giải pháp tốt nhất, đây có vẻ là cách tốt nhất và đơn giản nhất để đạt được một văn bản chỉnh sửa nhiều dòng mà không cần phím enter.
micnguyen

56

Một giải pháp thay thế để phân lớp con lớp EditText là định cấu hình cá thể EditText của bạn bằng:

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

Ít nhất, điều này hoạt động đối với tôi trên Android 4.0. Nó cấu hình cá thể EditText để người dùng chỉnh sửa một chuỗi đơn dòng được hiển thị với gói mềm trên nhiều dòng, ngay cả khi một hành động IME được đặt.


2
@Futzilogik: Bạn, thưa bạn, xứng đáng nhận được nhiều sự ủng hộ hơn nữa! Câu trả lời này là một phương pháp cứu mạng và cũng là một câu trả lời đơn giản. Ý tôi là, omg wow. Tôi ước tôi có thể ủng hộ nhiều hơn một lần. Cảm ơn rất nhiều!
Swayam

3
Tôi đang chạy 4.4.2 và điều này không hiệu quả với tôi hoặc ít nhất là cách làm của tôi. Tôi chỉ làm điều đó bằng XML, vì vậy có thể đó là một vấn đề. Tôi đã định cấu hình inputType thành "textEmailAddress | textMultiLine", scrollHoriz theo chiều ngang thành false, maxLines thành 500 (tệp xml), singleLine thành false và imeOptions thành actionNext. Tôi đã thử xóa "textMultiLine" khỏi kiểu nhập liệu. Với textMultiLine, tôi nhận được phím ENTER trên bàn phím và nếu không có phím này, mọi thứ vẫn nằm trên một dòng duy nhất và vẫn cuộn theo chiều ngang. Đây có vẻ là giải pháp dễ dàng nhất, nhưng giải pháp ở trên phù hợp với tôi, vì vậy hãy tiếp tục với nó ngay bây giờ.
react-core

6
Về nhận xét trước đây của tôi (không thể chỉnh sửa nó), nghi ngờ đó là vấn đề với việc không đặt MAX_VALUE hoặc chỉ thay đổi các nhận xét này sau khi văn bản chỉnh sửa được tạo, tôi đã thử trong mã như được chỉ ra ở đây và nó hoạt động! Tôi chỉ muốn đăng bài cho người khác, bạn không thể làm điều đó bằng XML (hoặc dù sao thì tôi cũng không thể). Các cài đặt khác tôi có: singleLine = false, imeOptions = actionNext, inputType = textEmailAddress (không có multiline).
lõi phản ứng

hoạt động rất tốt. Đây là một ví dụ điển hình về việc cải thiện câu trả lời cũ !!
nPn

Làm việc cho tôi trên Galaxy S5 chạy Lollipop. Giải pháp tuyệt vời. Lạ mà thiết cuộn theo chiều ngang trong xml không có cùng hiệu lực thi hành
Scott Birksted

7

Theo dõi câu trả lời trước

public class MultiLineText extends EditText {

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

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

    }

    public MultiLineText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnection connection = super.onCreateInputConnection(outAttrs);
        int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
        if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
            // clear the existing action
            outAttrs.imeOptions ^= imeActions;
            // set the DONE action
            outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
        }
        if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
            outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
        }
        return connection;
    }
}

Sử dụng như thế này

<myapp.commun.MultiLineText
  android:id="@+id/textNotes"
  android:layout_height="wrap_content"
  android:minHeight="100dp"
  android:layout_width="wrap_content"
  android:hint="Notes"
  android:textSize="20sp"
  android:padding="7dp"
  android:maxLines="4"/> 

5

để thực hiện hành động Xong, bạn có thể sử dụng:

XML

android:inputType="text|textCapSentences"    

JAVA

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

Tôi hy vọng công việc của nó cho bạn.


1

Rõ ràng câu trả lời cho câu hỏi ban đầu là Có nhưng tôi tin rằng nhóm Android đang cố gắng khiến các nhà phát triển suy nghĩ một chút về cách họ sử dụng EditText nhiều dòng. Họ muốn phím enter để thêm các dòng mới và có thể mong đợi rằng bạn cung cấp một nút hoặc một phương tiện nhập liệu khác để nâng cao sự kiện mà bạn đã chỉnh sửa xong.

Tôi gặp vấn đề tương tự và giải pháp rõ ràng của tôi là chỉ cần thêm một nút hoàn tất và để nút enter thêm các dòng mới.


Xin lỗi, tôi có thể đã không đủ rõ ràng với câu hỏi của mình .. nhiều dòng là để gói mềm một đầu vào một dòng. tức là các ký tự dòng mới không được phép.
ohhorob

@Mullins: Bạn đã thêm nút "xong" của riêng mình vào Bàn phím SoftInput chưa? Làm thế nào bạn làm điều đó trong khi vẫn giữ "Enter"?
alex.veprik

Không. Tôi đã tạo một nút hoàn tất trên giao diện người dùng tách biệt với bàn phím.
Mullins

1
Có lẽ nhóm Android nên làm theo lời khuyên của riêng họ và làm cho nút hành động của TextEdit nhiều dòng trong ứng dụng nhắn tin tạo dòng mới thay vì gửi tin nhắn.
Timmmm

0

Sử dụng các thuộc tính này trong XML của bạn.

android: inputType = "textImeMultiLine"

android: imeOptions = "actionDone"

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.