Làm cách nào để kiểm tra mức độ hiển thị của bàn phím phần mềm trong Android?


516

Tôi cần phải làm một việc rất đơn giản - tìm hiểu xem bàn phím phần mềm có được hiển thị không. Điều này có thể có trong Android?


9
Mặc dù câu trả lời của Reuben Scratton rất tốt nhưng dường như nó bị hỏng trên máy tính bảng. Tôi đã thay thế kiểm tra diff> 128 bằng diff> screenHeight / 3.
kingston

2
Câu trả lời của Reuben Scratton là tốt nhưng tôi yêu cầu sự điều chỉnh của KaChi để thực sự sử dụng nó.
Cullan

1
Tại sao Google không làm cho phương thức dựng sẵn tiêu chuẩn hoạt động cho tất cả các ứng dụng bàn phím?
Trái cây

4
Tôi vẫn nói với tôi rằng đây không phải là chức năng của hệ thống ...
longi 28/07/19

1
Thật tuyệt vời khi API này vẫn còn thiếu 10 năm sau . Rất vui vì tôi đã rời khỏi Android.
Reuben Scratton

Câu trả lời:


674

TRẢ LỜI MỚI được thêm vào ngày 25 tháng 1 năm 2012

Kể từ khi viết câu trả lời dưới đây, ai đó đã theo dõi tôi về sự tồn tại của ViewTreeObserver và bạn bè, các API đã ẩn trong SDK kể từ phiên bản 1.

Thay vì yêu cầu loại Bố cục tùy chỉnh, một giải pháp đơn giản hơn nhiều là cung cấp cho chế độ xem gốc của hoạt động của bạn một ID đã biết, giả sử @+id/activityRoot, móc GlobalLayoutListener vào ViewTreeObserver và từ đó tính toán kích thước khác nhau giữa gốc xem hoạt động của bạn và kích thước cửa sổ:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
        if (heightDiff > dpToPx(this, 200)) { // if more than 200 dp, it's probably a keyboard...
            // ... do something here
        }
     }
});

Sử dụng một tiện ích như:

public static float dpToPx(Context context, float valueInDp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}

Dễ dàng!

Lưu ý: Ứng dụng của bạn phải đặt cờ này trong Bản kê khai Android android:windowSoftInputMode="adjustResize"nếu không giải pháp trên sẽ không hoạt động.

CÂU TRẢ LỜI

Vâng, điều đó là có thể, nhưng nó khó hơn nhiều so với nó.

Nếu tôi cần quan tâm khi bàn phím xuất hiện và biến mất (điều này khá thường xuyên) thì việc tôi làm là tùy chỉnh lớp bố cục cấp cao nhất của mình thành một lớp ghi đè onMeasure(). Logic cơ bản là nếu bố cục thấy mình lấp đầy ít hơn đáng kể so với tổng diện tích của cửa sổ, thì có lẽ một bàn phím mềm sẽ hiển thị.

import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/*
 * LinearLayoutThatDetectsSoftKeyboard - a variant of LinearLayout that can detect when 
 * the soft keyboard is shown and hidden (something Android can't tell you, weirdly). 
 */

public class LinearLayoutThatDetectsSoftKeyboard extends LinearLayout {

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

    public interface Listener {
        public void onSoftKeyboardShown(boolean isShowing);
    }
    private Listener listener;
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity)getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff>128); // assume all soft keyboards are at least 128 pixels high
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);       
    }

    }

Sau đó, trong lớp Hoạt động của bạn ...

public class MyActivity extends Activity implements LinearLayoutThatDetectsSoftKeyboard.Listener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        LinearLayoutThatDetectsSoftKeyboard mainLayout = (LinearLayoutThatDetectsSoftKeyboard)findViewById(R.id.main);
        mainLayout.setListener(this);
        ...
    }


    @Override
    public void onSoftKeyboardShown(boolean isShowing) {
        // do whatever you need to do here
    }

    ...
}

62
Điều này không hiệu quả với tôi cho đến khi tôi nhận ra rằng bạn phải đặt thuộc tính sau cho hoạt động của mình: android: windowSoftInputMode = "điều chỉnh kích thước"
ajh158

9
Có vẻ như đang thực hiện các mẹo. Ngoài ra, nếu bạn không biết ID của chế độ xem gốc, đây là cách bạn có thể có được chế độ xem:((ViewGroup) findViewById(android.R.id.content)).getChildAt(0)
Thợ kim hoàn

8
Nếu bạn thử điều này bằng cách sử dụng chế độ xem gốc thực tế ( android.R.id.content), bạn sẽ có thể tự tin hơn nói rằng Systemthay vì ứng dụng của bạn là thực thể thay đổi chiều cao của nó. Sẽ an toàn hơn nhiều cho nhóm Android khi cho chúng tôi nghỉ ngơi và cho chúng tôi biết ít nhất những điều cơ bản về đầu vào SoftPal.
Graeme

14
Coi chừng heightDiffsẽ luôn bao gồm chiều cao của thanh hành động. Trong câu trả lời mới đã bị bỏ qua bằng cách kiểm tra nếu chiều cao đó lớn hơn một số hằng số, nhưng 100 pixel là không đủ cho các thiết bị xxhdpi như Nexus 4. Cân nhắc chuyển đổi giá trị đó thành DP nếu bạn thực sự muốn sử dụng công việc hack này- xung quanh.
Paul Lammertsma

8
Lưu ý: không hoạt động với WindowManager.LayoutParams.FLAG_FULLSCREEN và với chủ đề toàn màn hình.
VAV

303

Vì vậy, hy vọng điều này sẽ giúp ai đó.

Câu trả lời mới mà Reuben Scratton đưa ra là rất hay và thực sự hiệu quả, nhưng nó thực sự chỉ hoạt động nếu bạn đặt windowSoftInputMode thành điều chỉnhResize. Nếu bạn đặt nó thành điều chỉnhPan, bạn vẫn không thể phát hiện xem bàn phím có hiển thị hay không bằng đoạn mã của mình. Để khắc phục điều này, tôi đã thực hiện sửa đổi nhỏ này cho đoạn mã trên.

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    activityRootView.getWindowVisibleDisplayFrame(r);

    int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
    if (heightDiff > 0.25*activityRootView.getRootView().getHeight()) { // if more than 25% of the screen, its probably a keyboard...
        ... do something here
    }
 }
}); 

1
Đây là một trong những làm việc cho tôi. Tôi đã cố gắng phát hiện trạng thái bàn phím từ một tùy chỉnh TwoDScrollerViewtương tự như stackoverflow.com/a/5224088/530513 mặc dù cũng thu phóng. Đứa trẻ không đơn giản ImageViewmà là một bố cục tùy chỉnh (mở rộng RelativeLayout) nhưng không thể phát hiện bàn phím bằng giải pháp được đề xuất mặc dù đã cài đặt android:windowSoftInputMode="adjustResize". Cảm ơn!
David O'Meara

1
Cảm ơn bạn, cảm ơn bạn, cảm ơn bạn! điều chỉnh kích thước chỉ là không khả thi cho ứng dụng của tôi và giải pháp của bạn hoạt động hoàn hảo.
lùn

1
Làm việc với ActionBarActionBarSherlock. Cảm ơn rất nhiều! Nhân tiện, có một phương pháp r.height():)
Dmitry Zaytsev

1
Tôi sẽ đính kèm một tiền thưởng ở đây trong vòng 23 giờ để đánh dấu câu trả lời này bằng cách nào đó.
Dmitry Zaytsev

9
heightDiff > root.getRootView().getHeight() / 4là giá trị tốt để làm việc với thiết bị độ phân giải cao. 100px là ngắn. trong Nexus 5 với độ phân giải 1080x1920, 1920 - (996-75)>? 100 = 999 1920 - (1776-75)>? 100 = 219 // bàn phím lên trong galaxy s2 với độ phân giải 480x800, 800 - (800-38)>? 100 = 38 800 - (410-38)>? 100 = 428 // bàn phím đã hết, số ma thuật 100px không đủ tốt.
Flask_KR

55

Nó đã được mãi mãi về mặt máy tính nhưng câu hỏi này vẫn còn có liên quan không thể tin được!

Vì vậy, tôi đã thực hiện các câu trả lời ở trên và đã kết hợp và tinh chỉnh chúng một chút ...

public interface OnKeyboardVisibilityListener {


    void onVisibilityChanged(boolean visible);
}

public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
    final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);

    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        private boolean wasOpened;

        private final int DefaultKeyboardDP = 100;

        // From @nathanielwolf answer...  Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
        private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);

        private final Rect r = new Rect();

        @Override
        public void onGlobalLayout() {
            // Convert the dp to pixels.
            int estimatedKeyboardHeight = (int) TypedValue
                    .applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, activityRootView.getResources().getDisplayMetrics());

            // Conclude whether the keyboard is shown or not.
            activityRootView.getWindowVisibleDisplayFrame(r);
            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            boolean isShown = heightDiff >= estimatedKeyboardHeight;

            if (isShown == wasOpened) {
                Log.d("Keyboard state", "Ignoring global layout change...");
                return;
            }

            wasOpened = isShown;
            listener.onVisibilityChanged(isShown);
        }
    });
}

Làm việc cho tôi :)

LƯU Ý: Nếu bạn nhận thấy DefaultPalDP không phù hợp với thiết bị của bạn với giá trị và đăng nhận xét cho mọi người biết giá trị nào sẽ là ... cuối cùng chúng tôi sẽ nhận được giá trị chính xác để phù hợp với tất cả các thiết bị!

Để biết thêm chi tiết, hãy xem triển khai trên Cyborg


2
+1 Cảm ơn bạn rất nhiều !! Tôi đã thử các câu trả lời khác, nhưng chúng không hoạt động. Sau đó, tôi tìm thấy của bạn và nó hoạt động như một nét duyên dáng. Mã tuyệt vời! : D
Kevin van Mierlo

điều này chỉ hoạt động nếu bạn thêm: android: windowSoftInputMode = "stateHidden | điều chỉnhPan" hoặc android: windowSoftInputMode = "stateHidden | điều chỉnhResize" Cảm ơn bạn !!!!
Lena Bru

Bạn có chắc không? Nếu máy chủ bộ nhớ, tôi cũng nhận được các sự kiện đúng cách khi android: windowSoftInputMode có giá trị mặc định của nó ... điều duy nhất không giải quyết được là hoạt động của màn hình, vì vậy tôi đã thu nhỏ nó một cách thủ công ...
TacB0sS

2
một chỉnh sửa nhỏ: private Final int Ước tínhPalDP = DefaultPalDP + (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP? 48: 0);
binaryKarmic

2
Thông minh!! Bất kể "windowSoftInputMode" được đặt thành "điều chỉnhPan" / "điều chỉnhResize" / "điều chỉnhPan | stateHidden" / "điều chỉnhResize | stateHidden", hoặc thậm chí không có tùy chọn này, nó luôn hoạt động! Đã thử nghiệm trên XiaoMi 8.
Zhou Hongbo

52

Xin lỗi vì câu trả lời muộn, nhưng tôi đã tạo ra một lớp người trợ giúp nhỏ để xử lý các sự kiện mở / đóng với thông báo cho người nghe và những điều hữu ích khác, có thể ai đó sẽ thấy hữu ích:

import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;

import java.util.LinkedList;
import java.util.List;

public class SoftKeyboardStateWatcher implements ViewTreeObserver.OnGlobalLayoutListener {

    public interface SoftKeyboardStateListener {
        void onSoftKeyboardOpened(int keyboardHeightInPx);
        void onSoftKeyboardClosed();
    }

    private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
    private final View activityRootView;
    private int        lastSoftKeyboardHeightInPx;
    private boolean    isSoftKeyboardOpened;

    public SoftKeyboardStateWatcher(View activityRootView) {
        this(activityRootView, false);
    }

    public SoftKeyboardStateWatcher(View activityRootView, boolean isSoftKeyboardOpened) {
        this.activityRootView     = activityRootView;
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    @Override
    public void onGlobalLayout() {
        final Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
            isSoftKeyboardOpened = true;
            notifyOnSoftKeyboardOpened(heightDiff);
        } else if (isSoftKeyboardOpened && heightDiff < 100) {
            isSoftKeyboardOpened = false;
            notifyOnSoftKeyboardClosed();
        }
    }

    public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
        this.isSoftKeyboardOpened = isSoftKeyboardOpened;
    }

    public boolean isSoftKeyboardOpened() {
        return isSoftKeyboardOpened;
    }

    /**
     * Default value is zero {@code 0}.
     *
     * @return last saved keyboard height in px
     */
    public int getLastSoftKeyboardHeightInPx() {
        return lastSoftKeyboardHeightInPx;
    }

    public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.add(listener);
    }

    public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
        listeners.remove(listener);
    }

    private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
        this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;

        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardOpened(keyboardHeightInPx);
            }
        }
    }

    private void notifyOnSoftKeyboardClosed() {
        for (SoftKeyboardStateListener listener : listeners) {
            if (listener != null) {
                listener.onSoftKeyboardClosed();
            }
        }
    }
}

Ví dụ sử dụng:

final SoftKeyboardStateWatcher softKeyboardStateWatcher 
    = new SoftKeyboardStateWatcher(findViewById(R.id.activity_main_layout);

// Add listener
softKeyboardStateWatcher.addSoftKeyboardStateListener(...);
// then just handle callbacks

2
Lớp học không ít nhưng việc thực hiện chắc chắn là :). Cảm ơn tôi sẽ thử cái này :)
Atul O Holic

1
Ping tôi nếu bạn gặp vấn đề với nó :) Tôi đã sử dụng thành công nó trong 2 dự án
Artem Zinnatullin

Sau khi thử nhiều ví dụ ở trên và gặp phải các vấn đề nhỏ, đây là một trong những vấn đề phù hợp nhất với tôi trên nhiều thiết bị khác nhau (bao gồm cả xxhdpi). Thêm vào đó là trong lớp tái sử dụng tốt đẹp của riêng mình. Tôi đã chuyển đổi nó để được sử dụng trong mono droid.
khê

Một số bàn phím, đôi khi, có thêm một hàng phím tùy chỉnh ở trên cùng (ví dụ: các từ được dự đoán). Đây rõ ràng không phải là một phần của bàn phím, vì sử dụng getLastKeyboardHeightInPx()không bao gồm chiều cao của hàng đó. Bạn có biết một cách để đưa nó vào tài khoản là tốt?
ygesher

Điều này chỉ hoạt động nếu bạn sẵn sàng thỏa hiệp thay đổi chiều cao Bố cục khi bàn phím xuất hiện. đúng?
M. Usman Khan

33

Một số cải tiến để tránh phát hiện sai tầm nhìn của bàn phím mềm trên các thiết bị mật độ cao:

  1. Ngưỡng chênh lệch chiều cao phải được xác định là 128 dp , không phải 128 pixel .
    Tham khảo tài liệu thiết kế của Google về Metrics và Grid , 48 dp là kích thước thoải mái cho đối tượng cảm ứng và 32 dp là tối thiểu cho các nút. Bàn phím mềm chung phải bao gồm 4 hàng nút phím, vì vậy chiều cao bàn phím tối thiểu phải là: 32 dp * 4 = 128 dp , có nghĩa là kích thước ngưỡng sẽ chuyển sang pixel bằng cách nhân mật độ thiết bị. Đối với các thiết bị xxxhdpi (mật độ 4), ngưỡng chiều cao bàn phím mềm phải là 128 * 4 = 512 pixel.

  2. Chênh lệch chiều cao giữa chế độ xem gốc và khu vực hiển thị của nó:
    chiều cao của chế độ xem gốc - chiều cao của thanh trạng thái - chiều cao khung nhìn thấy = đáy ​​khung nhìn gốc - đáy khung hiển thị, vì chiều cao của thanh trạng thái bằng với đỉnh của khung nhìn thấy gốc.

    private final String TAG = "TextEditor";
    private TextView mTextEditor;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_editor);
        mTextEditor = (TextView) findViewById(R.id.text_editor);
        mTextEditor.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                isKeyboardShown(mTextEditor.getRootView());
            }
        });
    }
    
    private boolean isKeyboardShown(View rootView) {
        /* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */
        final int SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128;
    
        Rect r = new Rect();
        rootView.getWindowVisibleDisplayFrame(r);
        DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
        /* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */
        int heightDiff = rootView.getBottom() - r.bottom;
        /* Threshold size: dp to pixels, multiply with display density */
        boolean isKeyboardShown = heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density;
    
        Log.d(TAG, "isKeyboardShown ? " + isKeyboardShown + ", heightDiff:" + heightDiff + ", density:" + dm.density
                + "root view height:" + rootView.getHeight() + ", rect:" + r);
    
        return isKeyboardShown;
    }

4
Điều này xứng đáng là câu trả lời được chấp nhận. Bỏ qua mật độ cho tôi kết quả rất khác nhau trên các thiết bị có các yếu tố hình thức khác nhau nhưng kích thước pixel tương tự nhau. Cảm ơn!
Ginger McM bồ

2
Cảm ơn bạn ... đây là một điều kiện tốt hơn!
TacB0sS

1
Thông minh. Phương thức isPalShown () là những gì chúng ta cần. Cảm ơn
Danylo Volokh

Nó cũng hoạt động vào năm 2020. Câu trả lời hoàn hảo. Tôi đã thử tất cả các mã nhưng trên này hoạt động hoàn hảo.
Mitesh Jain

8

Tôi đã sử dụng một ít thời gian để tìm hiểu điều này ... Tôi đã chạy nó một số CastExceptions, nhưng đã tìm ra rằng bạn có thể thay thế bạn linearLayout trong layout.xml bằng tên của lớp.

Như thế này:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llMaster">

<com.ourshoppingnote.RelativeLayoutThatDetectsSoftKeyboard android:background="@drawable/metal_background"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:id="@+id/rlMaster" >
    <LinearLayout android:layout_width="fill_parent"
        android:layout_height="1dip" android:background="@drawable/line"></LinearLayout>

          ....

</com.ourshoppingnote.RelativeLayoutThatDetectsSoftKeyboard>    


</LinearLayout>

Bằng cách đó, bạn không gặp phải bất kỳ vấn đề nào.

... Và nếu bạn không muốn làm điều này trên mỗi trang, tôi khuyên bạn nên sử dụng "MasterPage trong Android". Xem liên kết tại đây: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx


Ồ, hãy cẩn thận về việc dán cái này vào XML của bạn nếu bạn không có cùng tên gói / lớp. Eclipse chỉ quyết định đóng băng và bạn phải tắt nó. Như một sản phẩm chuyên nghiệp. / s
Spencer Ruport

5
@SpencerRuport, đó là lý do tại sao nó miễn phí.
Cody

@DoctorOreo - nhận IntelliJ. Nó miễn phí và không hút.
Đánh dấu

@Mark - Một vài tháng sau khi tôi đăng bài này, tôi thực sự đã thử IntelliJ. IMO tốt hơn nhiều so với Eclipse. Tất cả các sản phẩm của họ (phần lớn) tôi nghĩ là tuyệt vời. Tôi thậm chí đã mua một vài.
Cody

Xin lỗi vì đã làm sống lại một chủ đề bình luận cũ. Tôi vui vì bạn đang sử dụng nó và tận hưởng nó. Tôi thích sử dụng IntelliJ cũng như AppCode cho iOS và PyCharm cho Python hoạt động. Chúc mừng!
Đánh dấu


5

Ý tưởng là, nếu bạn cần ẩn bàn phím và kiểm tra trạng thái nhập mềm cùng một lúc, hãy sử dụng giải pháp sau:

public boolean hideSoftInput() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
    return imm.hideSoftInputFromWindow(mViewPager.getWindowToken(), 0);
}

Phương pháp này trả về true nếu bàn phím được hiển thị trước khi ẩn.


Đây là một công trình không sử dụng chiều cao và tất cả ... Cảm ơn ... bạn đã tiết kiệm thời gian của tôi ...
Vji

4

Tôi thấy rằng sự kết hợp của phương pháp @ Reuben_Scratton cùng với phương pháp của @ Yogesh dường như hoạt động tốt nhất. Kết hợp các phương pháp của họ sẽ mang lại một cái gì đó như thế này:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  @Override
  public void onGlobalLayout() {
    if (getResources().getConfiguration().keyboardHidden == Configuration.KEYBOARDHIDDEN_NO) { // Check if keyboard is not hidden
       // ... do something here
    }
  }
});

luôn luôn Cấu hình.KEYBOARDHIDDEN_NO.
fantouch

4

Bạn có thể quan sát ẩn của phím chức năng bằng cách sử dụng decorView của hoạt động.

public final class SoftKeyboardUtil {
    public static final String TAG = "SoftKeyboardUtil";
    public static void observeSoftKeyBoard(Activity activity , final OnSoftKeyBoardHideListener listener){
        final View decorView = activity.getWindow().getDecorView();
        decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect rect = new Rect();
                decorView.getWindowVisibleDisplayFrame(rect);
                int displayHight = rect.bottom - rect.top;
                int hight = decorView.getHeight();
                boolean hide = (double)displayHight / hight > 0.8 ;
                if(Log.isLoggable(TAG, Log.DEBUG)){
                    Log.d(TAG ,"DecorView display hight = "+displayHight);
                    Log.d(TAG ,"DecorView hight = "+ hight);
                    Log.d(TAG, "softkeyboard visible = " + !hide);
                }

                listener.onSoftKeyBoardVisible(!hide);

            }
        });
    }



    public interface OnSoftKeyBoardHideListener{
        void onSoftKeyBoardVisible(boolean visible);
    }
}

4

Thay vì giả định mã hóa khác biệt, tôi đã làm một cái gì đó như thế này, vì tôi không có các tùy chọn menu trong ứng dụng của mình.

final View root= findViewById(R.id.myrootview); 
root.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
    public void onGlobalLayout() {
        int heightDiff = root.getRootView().getHeight() - root.getHeight();

        Rect rectgle= new Rect();
        Window window= getWindow();
        window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
        int contentViewTop=                     
          window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
        if(heightDiff <= contentViewTop){
            //Soft KeyBoard Hidden
        }else{
            //Soft KeyBoard Shown
        }
     }
});

Nó không hoạt động cho android: windowSoftInputMode = "điều chỉnhPan". Tôi muốn rằng màn hình của tôi không bị thu nhỏ sau khi bàn phím mềm xuất hiện. Bạn có thể vui lòng cho biết bất kỳ sửa chữa nào để nó hoạt động ngay cả đối với điều chỉnhPan
Shirish Herwade

4

Ngoài ra còn có giải pháp với phần tử hệ thống, nhưng nó chỉ hoạt động với API >= 21( Android L). Giả sử bạn có BottomNavigationView, là con của LinearLayoutvà bạn cần ẩn nó khi bàn phím được hiển thị:

> LinearLayout
  > ContentView
  > BottomNavigationView

Tất cả bạn cần làm là mở rộng LinearLayouttheo cách như vậy:

public class KeyboardAwareLinearLayout extends LinearLayout {
    public KeyboardAwareLinearLayout(Context context) {
        super(context);
    }

    public KeyboardAwareLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public KeyboardAwareLinearLayout(Context context,
                                     @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public KeyboardAwareLinearLayout(Context context, AttributeSet attrs,
                                     int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        int childCount = getChildCount();
        for (int index = 0; index < childCount; index++) {
            View view = getChildAt(index);
            if (view instanceof BottomNavigationView) {
                int bottom = insets.getSystemWindowInsetBottom();
                if (bottom >= ViewUtils.dpToPx(200)) {
                    // keyboard is shown
                    view.setVisibility(GONE);
                } else {
                    // keyboard is hidden
                    view.setVisibility(VISIBLE);
                }
            }
        }
        return insets;
    }
}

Ý tưởng là khi bàn phím được hiển thị, các phần tử hệ thống được thay đổi với .bottomgiá trị khá lớn .


4

Có một phương pháp ẩn có thể giúp cho việc này InputMethodManager.getInputMethodWindowVisibleHeight. Nhưng tôi không biết tại sao nó lại bị ẩn.

import android.content.Context
import android.os.Handler
import android.view.inputmethod.InputMethodManager

class SoftKeyboardStateWatcher(private val ctx: Context) {
  companion object {
    private const val DELAY = 10L
  }

  private val handler = Handler()
  private var isSoftKeyboardOpened: Boolean = false

  private val height: Int
    get() {
      val imm = ctx.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
      val method = imm.javaClass.getMethod("getInputMethodWindowVisibleHeight")
      method.isAccessible = true
      return method.invoke(imm) as Int
    }

  private val task: Runnable by lazy {
    Runnable {
      start()
      if (!isSoftKeyboardOpened && height > 0) {
        isSoftKeyboardOpened = true
        notifyOnSoftKeyboardOpened(height)
      } else if (isSoftKeyboardOpened && height == 0) {
        isSoftKeyboardOpened = false
        notifyOnSoftKeyboardClosed()
      }
    }
  }

  var listener: SoftKeyboardStateListener? = null

  interface SoftKeyboardStateListener {
    fun onSoftKeyboardOpened(keyboardHeightInPx: Int)
    fun onSoftKeyboardClosed()
  }

  fun start() {
    handler.postDelayed(task, DELAY)
  }

  fun stop() {
    handler.postDelayed({
      if (!isSoftKeyboardOpened) handler.removeCallbacks(task)
    }, DELAY * 10)
  }

  private fun notifyOnSoftKeyboardOpened(keyboardHeightInPx: Int) {
    listener?.onSoftKeyboardOpened(keyboardHeightInPx)
  }

  private fun notifyOnSoftKeyboardClosed() {
    listener?.onSoftKeyboardClosed()
  }
}

Nếu ai đó sẽ cần điều này - nó cũng hoạt động trong Xamarin, tên của phương thức hoàn toàn giống nhau và cần được truy cập theo cùng một cách - thông qua thuộc tính Class trên InputMethodManager.
Konstantin Severy

Hãy cẩn thận khi sử dụng, đây là API không được hỗ trợ (vì lý do này bị ẩn) và đối với người mới bắt đầu, nó không hoạt động trên KitKat.
Daniele Ricci

3

Không có giải pháp nào trong số này sẽ hoạt động cho Lollipop. Trong Lollipop activityRootView.getRootView().getHeight()bao gồm chiều cao của thanh nút, trong khi đo chế độ xem thì không. Tôi đã điều chỉnh giải pháp tốt nhất / đơn giản nhất ở trên để làm việc với Lollipop.

    final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  @Override
  public void onGlobalLayout() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    activityRootView.getWindowVisibleDisplayFrame(r);

    int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
    Resources res = getResources();
    // The status bar is 25dp, use 50dp for assurance
    float maxDiff =
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, res.getDisplayMetrics());

    //Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      float buttonBarHeight =
          TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48, res.getDisplayMetrics());
      maxDiff += buttonBarHeight;
    }
    if (heightDiff > maxDiff) { // if more than 100 pixels, its probably a keyboard...
      ...do something here
    }
  }
});

Tại sao giải pháp tương tự từ stackoverflow.com/a/18992807/2914140 lại hiệu quả với bạn và giải pháp của bạn khác nhau như thế nào?
CoolMind

3

Tôi vừa gặp một lỗi trong khi sử dụng hầu hết các giải pháp ở trên đề nghị thêm một số cố định.

S4 có dpi cao dẫn đến chiều cao của thanh điều hướng là 100px, do đó ứng dụng của tôi nghĩ rằng bàn phím luôn mở.

Vì vậy, với tất cả các điện thoại độ phân giải cao mới được phát hành, tôi tin rằng sử dụng giá trị mã hóa cứng không phải là ý tưởng tốt trong dài hạn.

Một cách tiếp cận tốt hơn mà tôi tìm thấy sau một số thử nghiệm trên các màn hình và thiết bị khác nhau là sử dụng tỷ lệ phần trăm. Nhận sự khác biệt giữa nội dung ứng dụng decorView và ur và sau đó kiểm tra tỷ lệ phần trăm của sự khác biệt đó là bao nhiêu. Từ các số liệu thống kê mà tôi có, hầu hết các thanh điều hướng (bất kể kích thước, độ phân giải, v.v.) sẽ chiếm từ 3% đến 5% màn hình. Nếu như bàn phím đang mở, nó chiếm từ 47% đến 55% màn hình.

Để kết luận, giải pháp của tôi là kiểm tra xem độ lệch có lớn hơn 10% hay không thì tôi giả sử nó là bàn phím mở.


3

Tôi đã sử dụng một biến thể nhỏ của câu trả lời của Reuban, điều này tỏ ra hữu ích hơn trong một số trường hợp nhất định, đặc biệt là với các thiết bị có độ phân giải cao.

final View activityRootView = findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
        new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                int heightView = activityRootView.getHeight();
                int widthView = activityRootView.getWidth();
                if (1.0 * widthView / heightView > 3) {
                    //Make changes for Keyboard not visible
                } else {
                    //Make changes for keyboard visible
                }
            }
        });

R.id.activityRoot này là gì
ranjith

2
thay vì tạo và sử dụng R.id.activityRoot, bạn chỉ cần sử dụng android.R.id.contentchính xác những gì bạn cần.
Marcin Orleansowski

3

Nó đã được mãi mãi về mặt máy tính nhưng câu hỏi này vẫn còn có liên quan không thể tin được! Vì vậy, tôi đã thực hiện các câu trả lời ở trên và đã kết hợp và tinh chỉnh chúng một chút ...

public interface OnKeyboardVisibilityListener {
    void onVisibilityChanged(boolean visible);
}

public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
    final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        private boolean wasOpened;

    private final Rect r = new Rect();

        @Override
        public void onGlobalLayout() {
            activityRootView.getWindowVisibleDisplayFrame(r);

            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            boolean isOpen = heightDiff > 100;
            if (isOpen == wasOpened) {
                logDebug("Ignoring global layout change...");
                return;
            }

            wasOpened = isOpen;
            listener.onVisibilityChanged(isOpen);
        }
    });
}

Nó làm việc cho tôi.


3

Thử cái này:

final View activityRootView = getWindow().getDecorView().getRootView();
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (heightDiff < activityRootView.getRootView().getHeight() / 4 ) { // if more than 100 pixels, its probably a keyboard...
             // ... do something here ... \\
        }
    }
});

2

Câu trả lời của tôi về cơ bản giống như câu trả lời của Kachi, nhưng tôi đã gói nó vào một lớp người trợ giúp tốt đẹp để dọn dẹp cách nó được sử dụng trong suốt ứng dụng của tôi.

import android.app.Activity;
import android.app.Fragment;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

/**
 * Detects Keyboard Status changes and fires events only once for each change
 */
public class KeyboardStatusDetector {
    KeyboardVisibilityListener visibilityListener;

    boolean keyboardVisible = false;

    public void registerFragment(Fragment f) {
        registerView(f.getView());
    }

    public void registerActivity(Activity a) {
        registerView(a.getWindow().getDecorView().findViewById(android.R.id.content));
    }

    public KeyboardStatusDetector registerView(final View v) {
        v.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                v.getWindowVisibleDisplayFrame(r);

                int heightDiff = v.getRootView().getHeight() - (r.bottom - r.top);
                if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
                    /** Check this variable to debounce layout events */
                    if(!keyboardVisible) {
                        keyboardVisible = true;
                        if(visibilityListener != null) visibilityListener.onVisibilityChanged(true);
                    }
                } else {
                    if(keyboardVisible) {
                        keyboardVisible = false;
                        if(visibilityListener != null) visibilityListener.onVisibilityChanged(false);
                    }
                }
            }
        });

        return this;
    }

    public KeyboardStatusDetector setVisibilityListener(KeyboardVisibilityListener listener) {
        visibilityListener = listener;
        return this;
    }

    public static interface KeyboardVisibilityListener {
        public void onVisibilityChanged(boolean keyboardVisible);
    }
}

Bạn có thể sử dụng điều này để phát hiện các thay đổi bàn phím ở bất cứ đâu trong suốt ứng dụng như thế này:

    new KeyboardStatusDetector()
            .registerFragment(fragment)  //register to a fragment 
            .registerActivity(activity)  //or register to an activity
            .registerView(view)          //or register to a view
            .setVisibilityListener(new KeyboardVisibilityListener() {
                @Override
                public void onVisibilityChanged(boolean keyboardVisible) {
                    if(keyboardVisible) {
                       //Do stuff for keyboard visible
                    }else {
                       //Do stuff for keyboard hidden
                    }
                }
            });

Lưu ý: chỉ sử dụng một trong các cuộc gọi "đăng ký". Tất cả đều hoạt động như nhau và chỉ ở đó để thuận tiện


2

bạn có thể thử điều này, làm việc tuyệt vời cho tôi:

InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);

if (imm.isAcceptingText()) {
    //Software Keyboard was shown..
} else {
    //Software Keyboard was not shown..
}

1
Đừng sử dụng cái này, nó sẽ trả về đúng nếu bàn phím bị ẩn khi sử dụng lại nhưng chế độ xem có tiêu điểm, ít nhất là trên Marshmallow
Maragues

2
luôn trả lời có thể nhìn thấy
jose920405

2

Tôi gặp khó khăn trong việc duy trì trạng thái bàn phím khi thay đổi hướng của các mảnh trong chế độ xem. Tôi không chắc tại sao, nhưng nó dường như rất mạnh mẽ và hoạt động khác với một Hoạt động tiêu chuẩn.

Để duy trì trạng thái bàn phím trong trường hợp này, trước tiên bạn nên thêm android:windowSoftInputMode = "stateUnchanged"vào AndroidManifest.xml. Tuy nhiên, bạn có thể nhận thấy rằng điều này thực sự không giải quyết được toàn bộ vấn đề - bàn phím không mở cho tôi nếu nó được mở trước đó trước khi thay đổi hướng. Trong tất cả các trường hợp khác, hành vi dường như là chính xác.

Sau đó, chúng ta cần thực hiện một trong những giải pháp được đề cập ở đây. Công cụ sạch nhất mà tôi tìm thấy là của George Maisuradze - sử dụng hàm gọi lại boolean từ hideSoftInputFromWindow:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
return imm.hideSoftInputFromWindow(mViewPager.getWindowToken(), 0);

Tôi đã lưu trữ giá trị này trong onSaveInstanceStatephương thức của Fragment và lấy nó onCreate. Sau đó, tôi buộc phải hiển thị bàn phím onCreateViewnếu nó có giá trị true(nó trả về đúng nếu bàn phím hiển thị trước khi thực sự ẩn bàn phím trước khi phá hủy Fragment).


1

Đây là giải pháp của tôi, và nó hoạt động. Thay vì tìm kích thước pixel, chỉ cần kiểm tra xem chiều cao của chế độ xem nội dung có thay đổi hay không:

// Scroll to the latest comment whenever the keyboard is shown
commentsContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        private int oldHeight;

        @Override
        public void onGlobalLayout() {
            int newHeight = commentsContent.getMeasuredHeight();
            if (newHeight < oldHeight) {
                // Check for the keyboard showing in case the height difference
                // is a result of orientation change
                if (isSoftKeyboardShowing(CommentsActivity.this)) {
                    // Keyboard is showing so scroll to the latest comment
                    scrollToLatestComment();
                }
            }
            oldHeight = newHeight;
        }

    });


public static boolean isSoftKeyboardShowing(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    return inputMethodManager.isActive();
}

inputMethodManager.isActive () luôn trả về đúng cho tôi, bất kể bàn phím có bật hay không
EionRobb

1

Đừng tạo bất kỳ mã cứng nào. Cách tốt nhất là bạn phải thay đổi kích thước lượt xem của mình trong khi tập trung vào EditText với KeyBord Show. Bạn có thể thực hiện việc thêm thay đổi kích thước thuộc tính trên hoạt động vào tệp Manifest bằng mã bên dưới.

android:windowSoftInputMode="adjustResize"


1

Có một phương pháp trực tiếp để tìm ra điều này. Và, nó không yêu cầu bất kỳ thay đổi Bố cục.
Vì vậy, nó cũng hoạt động ở chế độ toàn màn hình.

Mẹo nhỏ là bạn cố gắng ẩn hoặc hiển thị bàn phím mềm và nắm bắt kết quả của lần thử đó.
Không hoảng loạn, điều này không thực sự hiển thị hoặc ẩn bàn phím. Chúng tôi chỉ yêu cầu nhà nước.

Để luôn cập nhật, bạn chỉ cần lặp lại thao tác, ví dụ cứ sau 200 mili giây, sử dụng Trình xử lý.

Bạn tìm thấy một triển khai ở đây: https://stackoverflow.com/a/27567074/2525452


1

Tôi nghĩ rằng phương pháp này sẽ giúp bạn tìm ra liệu keybord có hiển thị hay không.

 public Boolean isSoftKeyBoardVisible(){
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    if (imm.isAcceptingText()) {
        Log.d(TAG,"Software Keyboard was shown");
        return true;
    } else {
        Log.d(TAG,"Software Keyboard was not shown");
        return false;
    }

}

luôn trả lời có thể nhìn thấy
jose920405

0

Câu trả lời mới của Reuben Scratton (tính toán Chiều cao int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight(); ) sẽ không hoạt động nếu bạn đặt chế độ thanh trạng thái mờ.

nếu bạn sử dụng thanh trạng thái mờ, activityRootView.getHeight() sẽ không bao giờ thay đổi thời tiết, bàn phím mềm sẽ hiển thị. nó sẽ luôn trả về chiều cao của hoạt động và thanh trạng thái.

Ví dụ: Nexus 4, Android 5.0.1, được đặt android:windowTranslucentStatusthành true, nó sẽ trả về 1184 mãi mãi, ngay cả ime cũng có ý kiến ​​phản đối. Nếu bạn đặtandroid:windowTranslucentStatus thành false, nó sẽ trả về Chiều cao chính xác, nếu ẩn, nó sẽ trả về 1134 (không bao gồm thanh trạng thái) hãy đóng ime, nó sẽ trả về 5xx có thể (tùy thuộc vào chiều cao của ime)

Tôi không biết thời tiết này là một lỗi, tôi đã thử trên 4.4.4 và 5.0.1, kết quả là như nhau.

Vì vậy, cho đến nay, câu trả lời đồng ý thứ hai, giải pháp của Kachi sẽ là cách an toàn nhất để tính chiều cao của ime. Đây là một bản sao:

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new        OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
activityRootView.getWindowVisibleDisplayFrame(r);

int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
    ... do something here
    }
 }
}); 

0

Một phương pháp mà không cần LayoutListener

Trong trường hợp của tôi, tôi muốn lưu trạng thái của bàn phím trước khi thay thế Fragment của mình. Tôi gọi phương thức hideSoftInputFromWindow từonSaveInstanceState đó, nó đóng bàn phím và trả về cho tôi xem bàn phím có nhìn thấy được hay không.

Phương pháp này đơn giản nhưng có thể thay đổi trạng thái bàn phím của bạn.


0

Tôi biết rằng đây là một bài viết cũ nhưng tôi nghĩ đây là cách tiếp cận đơn giản nhất mà tôi biết và thiết bị thử nghiệm của tôi là Nexus 5. Tôi chưa thử nó ở các thiết bị khác. Hy vọng rằng những người khác sẽ chia sẻ cách tiếp cận của họ nếu họ thấy mã của tôi không tốt :)

public static boolean isKeyboardShown(Context context, View view) {
        if (context == null || view == null) {
            return false;
        }
        InputMethodManager imm = (InputMethodManager) context
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        return imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 
}

im. leatherSoftInputFromWindow trả về boolean.

Cảm ơn,


0
if (keyopen())
{
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY,0);            
}

Chức năng trên là những gì tôi sử dụng để kiểm tra xem Bàn phím có hiển thị hay không. Nếu có, thì tôi đóng nó lại.

Dưới đây cho thấy hai phương pháp cần thiết.

Đầu tiên, xác định chiều cao cửa sổ có thể thực hiện được trong onCreate.

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//  add to onCreate method
    Rect rectgle= new Rect();
    Window window= getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
    sheight= rectgle.bottom;
//

} 

Sau đó, thêm một phương thức boolean lấy chiều cao Window tại trường hợp đó. Nếu nó không khớp với bản gốc (giả sử bạn không thay đổi nó trên đường đi ...) thì bàn phím đang mở.

public boolean keyopen()
{
    Rect rectgle= new Rect();
    Window window= getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
    int curheight= rectgle.bottom;

    if (curheight!=sheight)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Frotz!


0

Tôi biết chính xác làm thế nào bạn có thể xác định nếu bàn phím bị ẩn hay không.

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

public int getNavigationBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

public boolean isKeyboardHidden() {
    int delta = mRootView.getRootView().getHeight() - mRootView.getHeight() - getNavigationBarHeight() - getStatusBarHeight()
            - getSupportActionBar().getHeight();
    return delta <= 0;
}

Điều này làm việc cho máy tính bảng. Khi thanh điều hướng được hiển thị theo chiều ngang.

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.