web-dev-qa-db-ja.com

WhatsAppのようなソフトキーボードの上にビューを描画する方法は?

WhatsAppやHangoutのようなキーボードの上にViewを追加する方法を知りたい。チャット画面では、開いているソフトキーボードの上に絵文字ビューを挿入します。

sample image

誰もこの行動を達成する方法を知っていますか?

33
and_dev

さて、チャット用のサンプルキーボードを作成しました here ...

ここでは、ポップアップウィンドウを表示するためにポップアップウィンドウを使用し、ポップアップの高さはキーボードの高さによって動的に計算されます

// Initially defining default height of keyboard which is equal to 230 dip
        final float popUpheight = getResources().getDimension(
                R.dimen.keyboard_height);
        changeKeyboardHeight((int) popUpheight);

// Creating a pop window for emoticons keyboard
    popupWindow = new PopupWindow(popUpView, LayoutParams.MATCH_PARENT,
            (int) keyboardHeight, false);

この関数を使用して高さが計算されます:

/**
 * Checking keyboard height and keyboard visibility
 */
int previousHeightDiffrence = 0;
private void checkKeyboardHeight(final View parentLayout) {

    parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {

                    Rect r = new Rect();
                    parentLayout.getWindowVisibleDisplayFrame(r);

                    int screenHeight = parentLayout.getRootView()
                            .getHeight();
                    int heightDifference = screenHeight - (r.bottom);

                    if (previousHeightDiffrence - heightDifference > 50) {                          
                        popupWindow.dismiss();
                    }

                    previousHeightDiffrence = heightDifference;
                    if (heightDifference > 100) {

                        isKeyBoardVisible = true;
                        changeKeyboardHeight(heightDifference);

                    } else {

                        isKeyBoardVisible = false;

                    }

                }
            });

}

これらすべてを使って、完璧に重なり合うキーボードを作ることができます。

それから、絵文字用のviewpagerとgridviewでポップアップウィンドウを膨らませます。

また、リストビューとチャットウィンドウでこれらの絵文字を表示するために、スパン可能な文字列を使用します

19
Chirag Jain

かなりの時間をかけて試行錯誤を繰り返した結果、上記のChirag Jainに似たソリューションを見つけましたが、カスタムダイアログを使用しました。

    mDialogKeyboard = new Dialog(this,Android.R.style.Theme_NoTitleBar);
    mDialogKeyboard.setContentView(R.layout.your_custom_layout);
    mDialogKeyboard.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
    mDialogKeyboard.getWindow().setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
    mDialogKeyboard.getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    mDialogKeyboard.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

    WindowManager.LayoutParams lp=mDialogKeyboard.getWindow().getAttributes();    
    lp.width=WindowManager.LayoutParams.MATCH_PARENT;
    lp.height=mSoftKeyboardHeight;
    lp.gravity=Gravity.BOTTOM | Gravity.LEFT;
    lp.dimAmount=0;

Chirag Jain answerはよりクリーンであるという事実にもかかわらず、別の方法があるためにここに投稿します。

13
Parmaia

私の知る限り、他のアプリケーションを使用できます。はい。私自身はそのようなアプリを設計しました。キーボードなどのアプリケーションや特定の他のアプリケーションでの描画については、キーボードの高さとまったく同じ高さのレイアウトを定義する必要があると思います。したがって、それはデバイスごとに異なります。したがって、これは不可能です。

WhatsAppは、スマイリーボタンを押すとソフトキーボードを単に却下し、それを独自のフラグメントと呼びます。

それでもこれを追求したい場合は、他のアプリケーション上に「ウィンドウ」を描画する方法を次に示します。これらはレイアウトパラメータである必要があります。

params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.TRANSLUCENT);

とはいえ、アクティビティはキーボードのみで行うため、幅は絶対ピクセル値に変更されます。

質問を誤解した場合は、修正してください。

私は同じ問題に悩まされていました。やっとソフトキーボード上のPopupWindowを使用して解決できました。ソリューションをプロジェクトとしてgithubにアップロードしました: https://github.com/ankushsachdeva/emojicon

3
ankush

@jirkarrr、このようにkeyboardInfoContainerを追加してみませんか:

WindowManager wm = getWindowManager();
WindowManager.LayoutParams lps = new WindowManager.LayoutParams();
lps.x = 0; lps.y = keyboardHeight;
wm.addView(keyboardInfoContainer, lps);

私はあなたのコードとして行いますが、keyboardInfoContainerを表示できません。

0
GuangkaiRen

ポップアップを使用して、キーボード上にビューを配置します。

public void showPopUpKeyboard() {
        mIsPopupVisible = true;
        // Initialize a new instance of LayoutInflater service
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

        // Inflate the custom layout/view
        View customView = inflater.inflate(R.layout.popup_in_keyboard, null);


        mScrollView = (ScrollView) customView.findViewById(R.id.keyboard_layout_view);
        // Initialize a new instance of popup window
        mPopupWindow = new PopupWindow(
                customView,
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT
        );


        setSizeForSoftKeyboard();

        // Get a reference for the custom view close button
        Button closeButton = (Button) customView.findViewById(R.id.ib_close);

        // Set a click listener for the popup window close button
        closeButton.setOnClickListener((View view) -> {
                // Dismiss the popup window
                mIsPopupVisible = false;
                mPopupWindow.dismiss();
        });
        mPopupWindow.showAtLocation(mParentLayout, Gravity.CENTER, 0, 0);

    }

次に、キーボードの高さを確認しようとします:

mParentLayout.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
                Rect r = new Rect();

                mParentLayout.getWindowVisibleDisplayFrame(r);

                int heightDiff = mParentLayout.getRootView().getHeight() - (r.bottom - r.top);
                if (heightDiff > 100) {
                    //enter your code here
                    if (mIsPopupVisible) {
                        keepKeyboard();
                        mIsPopupVisible = false;
                        mPopupWindow.dismiss();
                    }
                } else {
                    //enter code for hid
                }
        }); 

これを確認できます tutorial and this GitHubの例

0
Cabezas

最近、ソフトキーボードの上にあるビューを実装する必要がありました。 @Chirag Jainのソリューションはほぼ正しいですが、画面の下部にあるシステムボタンではカウントされません!これにより、NEXUS 6などの一部のデバイスでキーボードの高さが不正確になります。このソリューションは、すべてのデバイスで機能するはずです。

1)ビューを含むレイアウトを作成する

<RelativeLayout
        Android:id="@+id/keyboard_info_container"
        Android:layout_width="match_parent"
        Android:layout_height="100dp"
        Android:layout_alignParentBottom="true"
        Android:background="@color/C12"
        Android:padding="10dp"
        Android:visibility="invisible">

           ....

    </RelativeLayout>

2)バインドビュー

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootview = inflater.inflate(R.layout.notifications_email_settings_fragment, container, false);

    ButterKnife.bind(this, rootview);

    checkKeyboardHeight(rootview);

3)キーボードチェックと表示マージン設定

private void checkKeyboardHeight(final View parentLayout) {

    parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {

                int previousHeightDiffrence = 0;
                int systemBarHigh = 999999;

                @Override
                public void onGlobalLayout() {


                    Rect r = new Rect();
                    parentLayout.getWindowVisibleDisplayFrame(r);

                    int screenHeight = parentLayout.getRootView()
                            .getHeight();
                    int keyboardHeight = screenHeight - (r.bottom);

                    if(systemBarHigh > keyboardHeight) {
                        systemBarHigh = keyboardHeight;
                    }

                    if (keyboardHeight > 250) {

                        int keyboardHightWithoutSystemBar = keyboardHeight - systemBarHigh;
                        // no need to update when the keyboard goes down
                        if (previousHeightDiffrence != keyboardHightWithoutSystemBar) { // if (Math.abs(previousHeightDiffrence - keyboardHeight) > 10) {
                            adjustKeyboard(keyboardHightWithoutSystemBar);
                        }

                        keyboardInfoContainer.setVisibility(View.VISIBLE);
                        isKeyBoardVisible = true;
                        previousHeightDiffrence = keyboardHightWithoutSystemBar;

                    } else {
                        isKeyBoardVisible = false;
                        if (keyboardInfoContainer != null) {
                            keyboardInfoContainer.setVisibility(View.INVISIBLE);
                        }
                    }
                }
            });
}

private void adjustKeyboard(int keyboardHeight) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) keyboardInfoContainer.getLayoutParams();
    lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    lp.bottomMargin = keyboardHeight;
    keyboardInfoContainer.requestLayout();
}
0
jirkarrrr

私の考えでは、彼らは笑顔のための独自のキーパッドを作成し、笑顔アイコンまたはキーパッドアイコンをクリックすると、笑顔のキーパッドを隠し、通常のキーパッドを表示しています。 whatsアプリのケースには2つのシナリオがあります1)editextの最初の時間に焦点を合わせないと、ショーキーパッドボタンが表示されず、笑顔キーパッドの高さは通常のキーパッドとまったく同じです、キーパッドの高さのみが取得されますビューレイアウトが変更された後、キーパッドが表示された後のみ、つまり独自のキーパッドを作成していることを意味します。2)編集テキストにフォーカスして笑顔ボタンをクリックすると、キーパッドボタンを表示するオプションが表示されますこれが正しくない場合

0
nilesh