2011-12-22 27 views
7

Tôi đang cố gắng phát hiện chiều cao bàn phím ảo trong Android.Cách gửi sự kiện con trỏ trong Android

Tôi tìm thấy một chủ đề tương tự: Get the height of virtual keyboard in Android

Có vẻ như tác giả đã tìm ra cách để phát hiện các height:

Tôi tìm thấy một cách để có được nó. Sau khi tôi yêu cầu mở bàn phím ảo, tôi gửi sự kiện con trỏ mà tôi tạo. tọa độ y của chúng bắt đầu từ chiều cao của thiết bị và giảm.

Tôi không hiểu cách thực hiện điều đó.

Trả lời

3

tôi sẽ sử dụng mã được cung cấp tại các liên kết mà bạn đã đăng:

// Declare Variables 

int softkeyboard_height = 0; 
boolean calculated_keyboard_height; 
Instrumentation instrumentation; 

// Initialize instrumentation sometime before starting the thread 
instrumentation = new Instrumentation(); 

mainScreenView là quan điểm cơ sở của bạn, quan điểm của hoạt động của bạn. m (ACTION_DOWN) và m1 (ACTION_UP) là các sự kiện chạm được gửi đi bằng cách sử dụng Instrumentation#sendPointerSync(MotionEvent). Logic là một MotionEvent cử đến nơi bàn phím đang được hiển thị sẽ gây ra những điều sau SecurityException:

java.lang.SecurityException: Tiêm một ứng dụng khác đòi hỏi INJECT_EVENTS phép

Vì vậy, chúng ta bắt đầu ở dưới cùng của màn hình và thực hiện theo cách của chúng tôi (bằng cách giảm y) trên mỗi lần lặp của vòng lặp. Đối với một số lần lặp nhất định, chúng ta sẽ nhận được một SecurityException (mà chúng ta sẽ bắt được): điều này có nghĩa là MotionEvent đang xảy ra trên bàn phím. Khoảnh khắc y bị đủ nhỏ (khi nó ngay trên bàn phím), chúng tôi sẽ thoát ra khỏi vòng lặp và tính toán chiều cao của bàn phím sử dụng:

softkeyboard_height = mainScreenView.getHeight() - y; 

Code:

Thread t = new Thread(){ 
     public void run() { 
      int y = mainScreenView.getHeight()-2; 
      int x = 10; 
      int counter = 0; 
      int height = y; 
      while (true){ 
       final MotionEvent m = MotionEvent.obtain(
         SystemClock.uptimeMillis(), 
         SystemClock.uptimeMillis(), 
         MotionEvent.ACTION_DOWN, 
         x, 
         y, 
         1); 
       final MotionEvent m1 = MotionEvent.obtain(
         SystemClock.uptimeMillis(), 
         SystemClock.uptimeMillis(), 
         MotionEvent.ACTION_UP, 
         x, 
         y, 
         1); 
       boolean pointer_on_softkeyboard = false; 
       try { 
        instrumentation.sendPointerSync(m); 
        instrumentation.sendPointerSync(m1); 
       } catch (SecurityException e) { 
        pointer_on_softkeyboard = true; 
       } 
       if (!pointer_on_softkeyboard){ 
        if (y == height){ 
         if (counter++ < 100){ 
          Thread.yield(); 
          continue; 
         } 
        } else if (y > 0){ 
         softkeyboard_height = mainScreenView.getHeight() - y; 
         Log.i("", "Soft Keyboard's height is: " + softkeyboard_height); 
        } 
        break; 
       } 
       y--; 

      } 
      if (softkeyboard_height > 0){ 
       // it is calculated and saved in softkeyboard_height 
      } else { 
       calculated_keyboard_height = false; 
      } 
     } 
    }; 
    t.start(); 

Instrumentation#sendPointerSync(MotionEvent):

Gửi sự kiện cho con trỏ. Kết thúc tại một số điểm sau khi người nhận đã trở lại từ quá trình xử lý sự kiện, mặc dù nó có thể không có hoàn thành phản hồi hoàn toàn từ sự kiện - ví dụ: nếu nó cần cập nhật kết quả hiển thị, nó vẫn có thể ở quá trình thực hiện điều đó.

+0

Đây có phải là API công khai không? Tôi không thể tìm thấy tài liệu về 'INTERNAL_POINTER_META_STATE'. – rid

+0

@rid Xin lỗi về điều đó. 'INTERNAL_POINTER_META_STATE' là hằng số nguyên. Đối với mục đích của câu hỏi, sử dụng bất kỳ giá trị số nguyên nào sẽ hoạt động. Tôi đã chỉnh sửa mã ở trên. Cảm ơn đã chỉ ra điều đó. – Vikram

+0

Tuy nhiên, có an toàn khi sử dụng tính năng này mà không có chức năng có khả năng biến mất trong bất kỳ phiên bản Android nào trong tương lai không? Đó có phải là '1' đảm bảo luôn giống nhau không? Có phải nó được ghi lại ở bất kỳ nơi nào chính thức bởi Google không? Bạn có thể dựa vào điều này mà không sợ sản xuất mã giòn? – rid

1

Sử dụng OnGlobalLayoutListener, nó hoạt động hoàn hảo cho tôi.

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