2012-05-10 41 views
5

Tôi đang cố gắng tạo tiện ích mã pin tùy chỉnh cho android thay thế cho chỉ sử dụng một thuộc tính inputType mật khẩu EditText. Điều tôi muốn hiển thị là một hàng các hộp và mỗi ô được điền khi người dùng nhập ghim của mình.Tiện ích nhập mã pin tùy chỉnh Android

Một người khác đã làm điều gì đó như thế này nhưng hóa ra là số lượng cố định EditText lượt xem và có rất nhiều mã xấu xí để hoán đổi trọng tâm làm ký tự được nhập hoặc xóa. Đây không phải là cách tiếp cận tôi muốn thực hiện; thay vào đó, tôi thiết kế mỏ của tôi có chiều dài có thể tùy chỉnh (dễ) và hoạt động như một khung nhìn đơn lẻ có thể lấy nét (không dễ dàng như vậy).

Khái niệm của tôi cho đến nay là một số loại lai giữa một LinearLayout (để giữ "hộp") và một EditText (để lưu trữ đầu vào của người dùng).

Đây là mã cho đến nay ...

public class PinCodeView extends LinearLayout { 
    protected static final int MAX_PIN_LENGTH = 10; 
    protected static final int MIN_PIN_LENGTH = 1; 

    protected int pinLength; 
    protected EditText mText; 

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

     TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PinCodeView); 
     try { 
      pinLength = a.getInt(R.styleable.PinCodeView_pinLength, 0); 
     } finally { 
      a.recycle(); 
     } 

     pinLength = Math.min(pinLength, MAX_PIN_LENGTH); 
     pinLength = Math.max(pinLength, MIN_PIN_LENGTH); 

     setupViews(); 

     Log.d(TAG, "PinCodeView initialized with pinLength = " + pinLength); 
    } 

    private void setupViews() { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
       Context.LAYOUT_INFLATER_SERVICE); 
     for (int i = 0; i < pinLength; i++) { 
      // inflate an ImageView and add it 
      View child = inflater.inflate(R.layout.pin_box, null, false); 
      addView(child); 
     } 
    } 

    public CharSequence getText() { 
     // TODO return pin code text instead 
     return null; 
    } 

    public int length() { 
     // TODO return length of typed pin instead 
     return pinLength; 
    } 

    @Override 
    public boolean onCheckIsTextEditor() { 
     return true; 
    } 

    @Override 
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 
     // TODO return an InputConnection 
     return null; 
    } 
} 

Về những ghi đè: onCheckIsTextEditor() nên trở thành sự thật và onCreateInputConnection(EditorInfo outAttrs) nên trả về một đối tượng mới InputConnection để tương tác với một InputMethod (bàn phím), nhưng đó là tất cả những gì biết.

Có ai biết tôi đang đi đúng hướng không? Có ai đã từng làm việc với InputConnection trước hoặc thực hiện chế độ xem có thể chỉnh sửa của riêng họ có thể đưa ra hướng dẫn không?

(Sửa 1) Sau khi xem xét này một số chi tiết, có vẻ như tôi nên phân lớp BaseInputConnection và cung cấp một TextView hoặc EditText như mục tiêu của nó:

@Override 
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) { 
     if (!onCheckIsTextEditor()) { 
      return null; 
     } 
     return new BaseInputConnection(mText, true); 
    } 

Giả sử điều này không lưu trữ các văn bản khi nó được đánh máy, Tôi vẫn cần một số cách để cập nhật các chế độ xem để phản ánh thay đổi nội dung ...

(Chỉnh sửa 2) Vì vậy, tôi đã thêm chế độ xem tùy chỉnh này vào màn hình để thử nghiệm. Nó cho thấy số lượng hộp, và toàn bộ khung nhìn có thể lấy nét, nhưng bàn phím không bao giờ bật lên. Tôi biết nó tăng/mất tập trung bởi vì các hộp hiển thị nổi bật một cách thích hợp và tôi đặt một OnFocusChangedListener để ghi vào logcat.

Điều gì khiến bàn phím thực xuất hiện khi chế độ xem có thể chỉnh sửa được lấy nét?

Trả lời

0

Tôi đã tiến bộ đáng kể về vấn đề này và không còn cần trợ giúp với InputConnection nữa. Tóm lại, bạn mở rộng BaseInputConnection và ghi đè getEditable() để trả lại Chỉnh sửa. Trong trường hợp này, tôi sẽ trả lại số TextView riêng được sử dụng trong nội bộ theo số PinCodeView. PinCodeView cũng ghi đè một số phương thức như onKey[foo]() và chuyển tiếp cuộc gọi đến số nội bộ TextView. Phần còn lại chỉ sử dụng TextWatcher để cập nhật một trong số các trẻ ImageView giây bất cứ khi nào văn bản thay đổi.

Nó hoạt động thực sự tốt. Vẫn còn một vài vấn đề nhỏ còn lại để đánh bóng nó, nhưng tôi sẽ giải quyết những vấn đề đó dưới dạng các câu hỏi riêng biệt và đóng nó ở đây.

+5

Nếu bạn cảm thấy hào phóng, điều đó sẽ rất tuyệt vời nếu mã này được tạo có sẵn trên github. Cảm ơn vì đăng! – saranicole

+0

Tôi thực sự thích, nhưng nó được sử dụng trong ứng dụng của công ty tôi, vì vậy tôi không biết rằng tôi có thể phát hành mã nguồn cho nó. Hãy để tôi kiểm tra nó với người quản lý của tôi. – Karakuri

+0

Bất kỳ cập nhật nào về việc phát hành điều này trên github hoặc nếu ai đó đã thực hiện những tiến bộ như vậy chưa? Các mã hiển thị ở đây trông thực sự hứa hẹn và một điểm khởi đầu tốt cho những người khác, mặc dù tôi thực sự đánh giá cao tổng số gói. Có lẽ Android cuối cùng sẽ thực hiện nó như một loại trường khác :) –

1

Có vẻ ổn với tôi. Điều bạn có thể muốn làm là khi người dùng nhập một ký tự vào một ô EditText, hãy tìm tham chiếu đến hộp EditText tiếp theo và thực hiện một số requestFocus() trên đó. Thao tác này sẽ di chuyển mục nhập văn bản vào hộp tiếp theo. Rất đơn giản.

+0

Đây là loại điều tôi đang cố gắng tránh. Toàn bộ tiện ích phải được đặt tiêu điểm, chứ không phải các hộp riêng lẻ. – Karakuri

+0

Các hộp riêng lẻ sẽ cần phải được tập trung để nhập vào chúng. Hơn nữa, một EditText tập trung sẽ có một đường màu xanh xung quanh nó, hiển thị cho người dùng rằng nó có thể lấy đầu vào. Nếu không có tín hiệu trực quan đó, người dùng sẽ không biết vị trí của nhân vật được nhập. –

+0

Có lẽ điều này không rõ ràng, nhưng tôi KHÔNG sử dụng một hàng EditTexts và tôi KHÔNG muốn mỗi hộp được tập trung riêng lẻ. Như tôi đã đề cập, tôi đã thấy mã cho điều đó và nó lộn xộn và xấu xí và blech. Cách tiếp cận này đang tăng cường ImageView cho các hộp và chúng sẽ có một bộ chọn có thể drawable làm nền của chúng và có duplicateParentState = "true" để chúng hiển thị trạng thái tập trung khi widget được lấy nét. Bu chìa khóa là các widget TOÀN BỘ được tập trung, không phải là các hộp cá nhân. – Karakuri

4

Dường như bạn có thể đang cố gắng tạo một tiện ích con dạng xem/ghim mục nhập iOS.

Đây là mã mẫu tốt mà bạn có thể thấy hữu ích. Tuy nhiên, nó là chiều dài cố định, nhưng vẫn có thể hữu ích cho một số người.

https://github.com/chinloong/Android-PinView

http://madeveloper.blogspot.com/2013/02/android-ios-like-pin-entrychallenge.html

+0

Tôi đánh giá cao ý kiến ​​của bạn, và nó có thể hữu ích cho người khác, nhưng tôi đã tự mình làm một giải pháp. Mỏ là một 'Chế độ xem 'tùy chỉnh đóng gói toàn bộ hàng của các hộp, tương tác với bàn phím Android và quản lý toàn bộ logic. Nó không yêu cầu toàn bộ hoạt động với toàn bộ bố cục các nút và bản xem trước. – Karakuri

+2

@Karakuri Vì bạn chưa cung cấp mã nguồn cũng như hướng dẫn chi tiết, câu trả lời này cho nhập mã pin, có liên quan hơn đối với tôi. –

2

Tôi biết điều này đã được trả lời nhưng vì thực hiện nó không được chia sẻ tôi tìm thấy một thư viện mã nguồn mở tương tự. Nó có vẻ tốt và cho tất cả những người lang thang có thể cho nó thử

https://github.com/Philio/PinEntryView

Các vấn đề liên quan