2013-02-15 22 views
7

Trong hầu hết các trường hợp, tôi muốn các sự kiện quan trọng được xử lý bởi chế độ xem (con) hiện có tiêu điểm, đó là hành vi mặc định và cũng là những gì tôi hiện đã triển khai.Trong Android, Ai có thể đánh chặn các sự kiện chính trên toàn cầu trước khi chúng đến được tầm nhìn trẻ em đã tập trung?

Tuy nhiên, trong một số trường hợp cụ thể, tôi muốn tạm thời đánh chặn và xử lý tất cả các sự kiện quan trọng (bao gồm cả các sự kiện thường được xử lý bởi chế độ xem con) hoặc trong hoạt động hiện tại của tôi hoặc không, trong chế độ xem gốc của tôi không quan trọng, miễn là chúng được xử lý trên toàn cầu - tôi không quan tâm đến các nút phần cứng như volume +/-, vì chúng không được xử lý trong bất kỳ chế độ xem con nào của tôi).

Đối lạc sự kiện, chúng tôi có onInterceptTouchEvent(), cho phép một ViewGroup để xem các sự kiện liên lạc như chúng được gửi đi để xem đứa trẻ, và để ngăn chặn nhận được những sự kiện đó (khi mong muốn) bởi các quan điểm con mà họ được dự định.

Thật không may, tôi không thể tìm thấy bất kỳ điều gì tương tự với onInterceptTouchEvent() cho các sự kiện chính. Tôi thiếu một cái gì đó hiển nhiên, hoặc đây là một bất đối xứng thực tế trong hệ điều hành? Tất nhiên, tôi chỉ có thể dây mã xử lý sự kiện khóa hiện tại của mỗi chế độ xem con để trực tiếp gọi một phương thức trên hoạt động chính để xử lý sự kiện nếu muốn và để phương thức mức hoạt động đó trả về một boolean cho biết liệu nó có xử lý sự kiện hay không. Sau đó, chế độ xem con có thể xử lý sự kiện nếu và chỉ khi phương thức hoạt động được gọi là không phải là đã xử lý sự kiện đó. Nhưng tôi hy vọng có một cách rõ ràng hơn để ngăn chặn lưu lượng truy cập trên đường "xuống" hệ thống phân cấp cho chế độ xem con, giống như onInterceptTouchEvent() làm cho các sự kiện cảm ứng.

+1

Lưu ý rằng tôi cũng quan tâm đến câu trả lời cho biết rằng điều này * không thể * được thực hiện. Nếu được xác minh, câu trả lời như vậy cũng có thể được chấp nhận. – Carl

+0

Tôi cũng tò mò muốn tìm hiểu lý do tại sao khả năng này sẽ tồn tại cho các sự kiện cảm ứng, nhưng không phải cho các sự kiện quan trọng, nếu đó thực sự là trường hợp. – Carl

Trả lời

0

Tất cả các tiện ích/Chế độ xem dường như thực hiện KeyEvent.Callback, có các phương thức được gọi để khóa, nhấn và giữ nhiều lần. Tất cả các phương thức này trả về giá trị boolean được giải thích là:

Nếu bạn xử lý sự kiện, trả về true. Nếu bạn muốn cho phép sự kiện được xử lý bởi người nhận tiếp theo, hãy trả về false.

Tôi nghĩ bạn có thể thử ghi đè các phương thức này trong các thành phần chính.

Một số khác là dispatchKeyEvent() của View nó xử lý việc gửi sự kiện xuống đường tiêu điểm. Việc ghi đè điều này cũng có thể được thử.

+0

Cảm ơn bạn đã trả lời. 1) Trừ khi tôi nhầm, các phương thức được khai báo bởi giao diện KeyEvent.Callback, chẳng hạn như onKeyDown(), được gọi trước tiên cho khung nhìn hiện có tiêu điểm. Chỉ khi quan điểm đó trả về false từ một trong những phương thức khác, tổ tiên, lượt xem có được một shot ở đó. Tôi quan tâm đến việc có chế độ xem gốc (hoặc hoạt động) có quyền truy cập vào các sự kiện * trước * chế độ xem có tiêu điểm. 2) Tôi tin rằng dispatchKeyEvent() * tạo * một sự kiện chính lập trình. Những gì tôi đang cố gắng làm là * chặn * một sự kiện được tạo ra như là kết quả của * người dùng * đã khai thác một phím trên bàn phím. – Carl

+0

Tôi hiểu. Làm thế nào về lấy và giữ tập trung? –

+0

Hmm, vâng, tôi có thể thấy một số người phải đối mặt với một vấn đề tương tự có thể có cách tiếp cận, ví dụ, gọi setFocusable (false) cho các quan điểm trẻ em, nếu đó là những gì bạn nghĩ. Vấn đề với điều đó đối với tôi là tôi muốn người dùng có thể tiếp tục sử dụng cảm ứng trong các chế độ xem đó để chọn và điều hướng. Tôi chỉ muốn vô hiệu hóa chế độ nhập bằng bàn phím của các chế độ xem con đó và thay thế bằng chế độ toàn cục của cùng một lần nhấn phím, khi phát hiện một số điều kiện nhất định (ở mức toàn cục). – Carl

0

Ghi đè dispatchKeyEvent trong ViewGroup là tổ tiên cho các công trình bị vô hiệu hóa View.

Tôi đang sử dụng thông tin sau ~.

public static class TvPrefsContainer extends FrameLayout { 
    private boolean isActive; // i.e. will dispatch keyboard events to focused children 
    // snip 

    @Override public boolean dispatchKeyEvent(KeyEvent event) { 
     return isActive && super.dispatchKeyEvent(event); 
    } 
} 

public static class TvPrefs extends PreferenceFragment { 
    @Override public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     addPreferencesFromResource(R.xml.tv_prefs); 
    } 
} 

private void togglePrefsVis() { 
    tvPrefsContainer.animate() 
      .alpha(isPrefsVisible ? 0 : 1) 
      .translationX(isPrefsVisible ? tvPrefsContainer.getMeasuredWidth() : 0) 
      .start(); 
    tvPrefsContainer.isActive = isPrefsVisible; 
    isPrefsVisible = !isPrefsVisible; 
} 
+0

Tôi sai về 'isActivated'. Ít nhất nó góp phần vào các trạng thái được sử dụng cho StateListDrawables – nmr

+0

Tôi nghĩ dispatchKeyEventPreIme (http://developer.android.com/reference/android/view/ViewGroup.html#dispatchKeyEventPreIme(android.view.KeyEvent)) sẽ hữu ích hơn – Grimmy

0

Bạn có thể thêm OnGlobalFocusChangeListener vào chế độ xem gốc của mình. Hãy làm điều đó mỗi hoạt động:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    findViewById(android.R.id.content).getViewTreeObserver().addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() { 
     @Override 
     public void onGlobalFocusChanged(View oldFocus, View newFocus) { 
      if (newFocus instanceof EditText) { 
       ((EditText) newFocus).addTextChangedListener(new TextWatcher() { 
        @Override 
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
         //process whatever you want 
        } 

        @Override 
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 
        } 

        @Override 
        public void afterTextChanged(Editable editable) { 
        } 
       }); 
      } 
     } 
    }); 
} 

Tất nhiên nếu bạn quan tâm đến quan điểm khác hơn EditText bạn phải tìm ra cách để quan sát những thay đổi của họ.

Đồng thời, nếu bạn muốn thêm toàn cầu vào tất cả hoạt động của mình, hãy sử dụng Application#registerActivityLifecycleCallbacks() để sử dụng mã đó trong tất cả các hoạt động của bạn.

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