Androidソフトキーボードが表示されているときに全画面モードでレイアウトを調整する方法


178

ソフトキーボードがアクティブなときにレイアウトを調整するために多くの調査を行い、それを正常に実装しましたが、android:theme="@android:style/Theme.NoTitleBar.Fullscreen"マニフェストファイルのアクティビティタグでこれを使用すると問題が発生します。

このため、私はandroid:windowSoftInputMode="adjustPan|adjustResize|stateHidden"さまざまなオプションを使用しましたが、運はありませんでした。

その後、FullScreenプログラムで実装し、さまざまなレイアウトを試してみましたFullScreenが、すべてが無駄でした。

私はこれらのリンクを参照し、この問題に関連するここで多くの投稿を見てきました:

http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html

http://davidwparker.com/2011/08/30/android-how-to-float-a-row-above-keyboard/

ここにxmlコードがあります:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/masterContainerView"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="#ffffff">

    <ScrollView android:id="@+id/parentScrollView"
        android:layout_width="fill_parent" android:layout_height="wrap_content">

        <LinearLayout android:layout_width="fill_parent"
            android:layout_height="fill_parent" android:orientation="vertical">

            <TextView android:id="@+id/setup_txt" android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:text="Setup - Step 1 of 3"
                android:textColor="@color/top_header_txt_color" android:textSize="20dp"
                android:padding="8dp" android:gravity="center_horizontal" />

            <TextView android:id="@+id/txt_header" android:layout_width="fill_parent"
                android:layout_height="40dp" android:text="AutoReply:"
                android:textColor="@color/top_header_txt_color" android:textSize="14dp"
                android:textStyle="bold" android:padding="10dp"
                android:layout_below="@+id/setup_txt" />

            <EditText android:id="@+id/edit_message"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:text="Some text here." android:textSize="16dp"
                android:textColor="@color/setting_editmsg_color" android:padding="10dp"
                android:minLines="5" android:maxLines="6" android:layout_below="@+id/txt_header"
                android:gravity="top" android:scrollbars="vertical"
                android:maxLength="132" />

            <ImageView android:id="@+id/image_bottom"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:layout_below="@+id/edit_message" />

        </LinearLayout>
    </ScrollView>

    <RelativeLayout android:id="@+id/scoringContainerView"
        android:layout_width="fill_parent" android:layout_height="50px"
        android:orientation="vertical" android:layout_alignParentBottom="true"
        android:background="#535254">

        <Button android:id="@+id/btn_save" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_alignParentRight="true"
            android:layout_marginTop="7dp" android:layout_marginRight="15dp"
            android:layout_below="@+id/edit_message"
            android:text = "Save" />

        <Button android:id="@+id/btn_cancel" android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_marginTop="7dp"
            android:layout_marginRight="10dp" android:layout_below="@+id/edit_message"
            android:layout_toLeftOf="@+id/btn_save" android:text = "Cancel" />

    </RelativeLayout>
</RelativeLayout>

ここに画像の説明を入力してください

ソフトキーボードが画面に表示されたら、下の2つのボタンを上に向けてください。

ここに画像の説明を入力してください


1
ScrollView内とEditTextの下にボタンを追加する必要があると思います。
Balaji Khadake、2011

私はすでにうまくいかない多くのオプションを試しました...
Vineet Shukla

1
でframeLayoutでウルボタンを入れて、1でframeLayoutの重みを設定し、最終的にのみ使用android:windowSoftInputMode="adjustPan"を教えている場合は、この作品...
シェリフelKhatib

@VineetShuklaフルスクリーンで何か解決策を見つけましたか?
Muhammad Babar 2013

2
あなたが使用してはならないことに注意してくださいadjustResizeadjustPanのjavadocをから、同時にandroid.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE「これは{@link} SOFT_INPUT_ADJUST_PANと組み合わせることはできません」
デニスKniazhev

回答:


257

yghmの回避策に基づいて、ワンライナーで問題を解決できる便利なクラスをコード化しました(もちろん、新しいクラスをソースコードに追加した後)。ワンライナーは:

     AndroidBug5497Workaround.assistActivity(this);

そして実装クラスは:


public class AndroidBug5497Workaround {

    // For more information, see https://issuetracker.google.com/issues/36911528
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }
}

これが誰かを助けることを願っています。


8
ありがとう!私はなぜわかりませんが、私は交換していたreturn (r.bottom - r.top);return r.bottom、それはそれ以外のアクティビティビューは、ステータスバーのサイズによって高すぎるプッシュされるだろう、私のHTCワンミニで作業を取得します。私はまだそれを別のデバイスでテストしていません。お役に立てれば幸いです。
Joan

4
こんにちはジョセフジョンソン、私はあなたのコードを使用しました、そしてそれは完全に働きました。しかし、今日では、一部の小型デバイスでキーボードとレイアウトのギャップ(空白の画面)が表示されるという問題に直面しています。この問題について何か考えがありますか?また、r.bottomを返してみました。
Pankaj 2014

2
ジョセフ・ジョンソン:私はあなたの方法を実装しました、上の編集テキストをクリックするとうまくいきますが、下の編集テキストをクリックするとすべてのデザインが上がります
ranjith

3
残念ながら、Nexus 7(2013)では機能しません。adjustNothingが設定されていてもパンします。
Le-roy Staines 2014年

4
すばらしい回答、ありがとうございました。これはNexus 6で動作しframeLayoutParams.height = usableHeightSansKeyboard;ますが、使用する代わりに使用する必要frameLayoutParams.height = usableHeightNow; があります。使用しない場合、一部の要素が画面の外に出ます。
RobertoAllende

36

答えはすでに選択されており、問題はバグであることがわかっているので、「可能な回避策」を追加すると思いました。

ソフトキーボードが表示されているときにフルスクリーンモードを切り替えることができます。これにより、「adjustPan」が正しく機能します。

つまり、アプリケーションテーマの一部として@android:style / Theme.Black.NoTitleBar.Fullscreenを使用し、アクティビティウィンドウのソフト入力モードの一部としてstateVisible | adjustResizeを使用しますが、それらを連携させるには、フルスクリーンモードを切り替える必要がありますキーボードが表示される前。

次のコードを使用します。

全画面モードをオフにする

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

全画面モードをオンにする

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);

注-インスピレーションの源:全画面モードでタイトルを非表示にする


1
問題に時間を割いていただきありがとうございます。私は間違いなくこのアプローチをテストし、それがうまくいったかどうかすぐにお知らせします。ありがとうございます。
Vineet Shukla

1
疑いどおりに動作しています!本当に良い解決策です!私の側から+1。
Mike


1
キーボードがスナップし、キーボードの背景が黒くなります。スナップ効果が良く見えない:(
nibz

おかげですごい...それは回避策がAndroidBug5497Workaround言及組み合わせることによって、本当によく私の作品...私はGitHubの...に合わせてソースをアップロードgithub.com/CrandellWS/AndroidBug5497Workaround/blob/master/...
CrandellWS

23

Joseph Johnson解決策を試しましたが、他のコンテンツと同様に、コンテンツとキーボードの間のギャップの問題に遭遇しました。この問題は、フルスクリーンモードを使用する場合、ソフト入力モードが常にパンになるために発生します。このパニングは、ソフト入力によって非表示になる入力フィールドをアクティブにすると、ジョセフのソリューションを妨害します。

ソフト入力が表示されると、コンテンツは最初に元の高さに基づいてパンされ、次にジョセフのソリューションによって要求されたレイアウトによってサイズ変更されます。サイズ変更とその後のレイアウトではパンが元に戻されず、ギャップが生じます。イベントの完全な順序は次のとおりです。

  1. グローバルレイアウトリスナー
  2. パンニング
  3. コンテンツのレイアウト(=コンテンツの実際のサイズ変更)

パンを無効にすることはできませんが、コンテンツの高さを変更することにより、パンオフセットを強制的に0にすることができます。パンが行われる前に実行されるため、これはリスナーで実行できます。コンテンツの高さを利用可能な高さに設定すると、スムーズなユーザーエクスペリエンス、つまりちらつきがなくなります。

これらの変更も行いました。これらのいずれかで問題が発生した場合は、お知らせください。

  • 使用可能な高さの決定を切り替えましたgetWindowVisibleDisplayFrameRect不要なゴミを少し防ぐためにキャッシュされます。
  • リスナーも削除できるようにします。これは、フルスクリーン要件が異なるさまざまなフラグメントのアクティビティを再利用する場合に役立ちます。
  • キーボードの表示と非表示を区別せず、常にコンテンツの高さを表示可能なディスプレイフレームの高さに設定します。

これは、Nexus 5、およびAPIレベル16〜24を実行し、画面サイズが小さいものから大きいものまでのエミュレーターでテストされています。

コードはKotlinに移植されていますが、変更をJavaに移植するのは簡単です。サポートが必要な場合はお知らせください:

class AndroidBug5497Workaround constructor(activity: Activity) {
    private val contentContainer = activity.findViewById(android.R.id.content) as ViewGroup
    private val rootView = contentContainer.getChildAt(0)
    private val rootViewLayout = rootView.layoutParams as FrameLayout.LayoutParams
    private val viewTreeObserver = rootView.viewTreeObserver
    private val listener = ViewTreeObserver.OnGlobalLayoutListener { possiblyResizeChildOfContent() }

    private val contentAreaOfWindowBounds = Rect()
    private var usableHeightPrevious = 0

    // I call this in "onResume()" of my fragment
    fun addListener() {
        viewTreeObserver.addOnGlobalLayoutListener(listener)
    }

    // I call this in "onPause()" of my fragment
    fun removeListener() {
        viewTreeObserver.removeOnGlobalLayoutListener(listener)
    }

    private fun possiblyResizeChildOfContent() {
        contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
        val usableHeightNow = contentAreaOfWindowBounds.height()
        if (usableHeightNow != usableHeightPrevious) {
            rootViewLayout.height = usableHeightNow
            // Change the bounds of the root view to prevent gap between keyboard and content, and top of content positioned above top screen edge.
            rootView.layout(contentAreaOfWindowBounds.left, contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom)
            rootView.requestLayout()

            usableHeightPrevious = usableHeightNow
        }
    }
}

9
これが最良の答えのようです。ここgist.github.com/grennis/2e3cd5f7a9238c59861015ce0a7c5584で Javaに移植しました。オブザーバーが生存していないという例外が発生し、それも確認する必要があったことに注意してください。
グレッグエニス2017

何てことだ!そのゴーストスペースを探して、すべてのシステムビュー階層をトラバースしています。私はフードトラックのコンピューターを捨てるところだったが、最後の方であなたの答えを見た。それは動作します:)
2018年

1
@Greg Ennis Javaへの移植に感謝します。多くの労力と時間を節約しました。
Ikun

@GregEnnis、ありがとうございます。ソリューションはonResume()、onPause()、onDestroy()で動作します(GitHubコードのコメントを参照)。
CoolMind 2018年

これは私にとっては機能していますが、removeListener呼び出しが機能していないようです。possiblyResizeChildOfContent呼び出しと呼び出しの両方にブレークポイントを配置removeListenerし、removeListenerブレークポイントにヒットした後possiblyResizeChildOfContentも呼び出されています。この問題を抱えている他の人はいますか?
Quinn

14

システムUIアプローチ(https://developer.android.com/training/system-ui/immersive.html)を使用している場合は、シンプルで信頼できるソリューションを見つけました。

これはView.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN、たとえばを使用している場合などに使用できますCoordinatorLayout

それは動作しませんWindowManager.LayoutParams.FLAG_FULLSCREEN(あなたも持つテーマに設定することができます1 android:windowFullscreen)、しかし、あなたはと同様の効果を達成することができますSYSTEM_UI_FLAG_LAYOUT_STABLE(「同じ視覚効果がある」ドキュメントに応じて)、この溶液を再び動作するはずです。

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /* If you want to hide navigation */
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE)

マシュマロを実行しているデバイスでテストしました。

重要なのは、ソフトキーボードはシステムウィンドウ(ステータスバーやナビゲーションバーなど)の1つでもあるため、WindowInsetsシステムによってディスパッチされるのは、それに関する正確で信頼できる情報です。

DrawerLayoutステータスバーの背後に描画しようとしている場合などの使用例では、上部のインセットのみを無視し、ソフトキーボードを考慮した下部のインセットを適用するレイアウトを作成できます。

これが私の習慣FrameLayoutです:

/**
 * Implements an effect similar to {@code android:fitsSystemWindows="true"} on Lollipop or higher,
 * except ignoring the top system window inset. {@code android:fitsSystemWindows="true"} does not
 * and should not be set on this layout.
 */
public class FitsSystemWindowsExceptTopFrameLayout extends FrameLayout {

    public FitsSystemWindowsExceptTopFrameLayout(Context context) {
        super(context);
    }

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

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

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    public FitsSystemWindowsExceptTopFrameLayout(Context context, AttributeSet attrs,
                                                 int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            setPadding(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(),
                    insets.getSystemWindowInsetBottom());
            return insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(), 0, 0);
        } else {
            return super.onApplyWindowInsets(insets);
        }
    }
}

そしてそれを使うには:

<com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Your original layout here -->
</com.example.yourapplication.FitsSystemWindowsExceptTopFrameLayout>

これは理論上、狂ったように変更することなくどのデバイスでも機能するはずです。ランダム1/3または1/4画面サイズを参照として試みるハッキングよりもはるかに優れています。

(API 16+が必要ですが、ステータスバーの背後に描画するためにLollipop +でのみフルスクリーンを使用しているため、この場合に最適です。)


@Dilip上記の条件が満たされていれば、API 16以降で動作します。
Hai Zhang

10

がアクティビティに設定されているandroid:windowSoftInputMode="adjustResize"場合WindowManager.LayoutParams.FLAG_FULLSCREENは機能しませんのでご注意ください。2つのオプションがあります。

  1. アクティビティのフルスクリーンモードを無効にしてください。フルスクリーンモードでは、アクティビティのサイズは変更されません。これは、xml(アクティビティのテーマを変更することにより)またはJavaコードで行うことができます。onCreate()メソッドに次の行を追加します。

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);   
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);`

または

  1. 全画面モードを実現するには、別の方法を使用します。onCreate()メソッドに次のコードを追加します。

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    View decorView = getWindow().getDecorView();
    // Hide the status bar.
    int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
    decorView.setSystemUiVisibility(uiOptions);`

method-2はAndroid 4.1以降でのみ機能することに注意してください。


@AnshulTyagi method-2は、Android 4.1以降でのみ機能します。
Abhinav Chauhan 2015年

4
5.0および4.4.2、Nexus 9およびSamsung s4でそれぞれテストされ、2番目の方法は機能しません。
RobVoisey 2015年

1
2番目の方法は単純に機能せず、多くの時間を費やしました。
グレッグエニス2017

ありがとう、私の日を保存してください。
Deni Rohimat

9

私もこの問題に直面しなければならず、HTC one、galaxy s1、s2、s3、note、HTC sensationをチェックする作業をしました。

レイアウトのルートビューにグローバルレイアウトリスナーを配置する

mRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
            public void onGlobalLayout() {
                checkHeightDifference();
            }
    });

そこで高さの差を確認しました。画面の高さの差が画面の高さの3分の1より大きい場合は、キーボードが開いていると想定できます。この答えからそれを取った。

private void checkHeightDifference(){
    // get screen frame rectangle 
    Rect r = new Rect();
    mRootView.getWindowVisibleDisplayFrame(r);
    // get screen height
    int screenHeight = mRootView.getRootView().getHeight();
    // calculate the height difference
    int heightDifference = screenHeight - (r.bottom - r.top);

    // if height difference is different then the last height difference and
    // is bigger then a third of the screen we can assume the keyboard is open
    if (heightDifference > screenHeight/3 && heightDifference != mLastHeightDifferece) {
        // keyboard visiblevisible
        // get root view layout params
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        // set the root view height to screen height minus the height difference
        lp.height = screenHeight - heightDifference;
        // call request layout so the changes will take affect
        .requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    } else if (heightDifference != mLastHeightDifferece) {
        // keyboard hidden
        PFLog.d("[ChatroomActivity] checkHeightDifference keyboard hidden");
        // get root view layout params and reset all the changes we have made when the keyboard opened.
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mRootView.getLayoutParams();
        lp.height = screenHeight;
        // call request layout so the changes will take affect
        mRootView.requestLayout();
        // save the height difference so we will run this code only when a change occurs.
        mLastHeightDifferece = heightDifference;
    }
}

これはおそらく完全な証拠ではなく、おそらく一部のデバイスでは機能しませんが、私にとっては機能し、あなたにも役立つことを願っています。


1
いくつかの調整が必要でしたが、うまくいきました。Nexus 7 2013では、キーボードの高さ(screenHeight / 3)を数ピクセル下げる必要がありました。いいアイデア、ありがとう!
Joao Sousa

7

私はジョセフジョンソンソリューションを実装しましたが、うまく機能しました。このソリューションを使用した後、アプリケーションの引き出しが正しく閉じない場合があることに気付きました。edittextが配置されているフラグメントをユーザーが閉じるときに、リスナーremoveOnGlobalLayoutListenerを削除する機能を追加しました。

    //when the application uses full screen theme and the keyboard is shown the content not scrollable! 
//with this util it will be scrollable once again
//http://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible
public class AndroidBug5497Workaround {


    private static AndroidBug5497Workaround mInstance = null;
    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;
    private ViewTreeObserver.OnGlobalLayoutListener _globalListener;

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static AndroidBug5497Workaround getInstance (Activity activity) {
        if(mInstance==null)
        {
            synchronized (AndroidBug5497Workaround.class)
            {
                mInstance = new AndroidBug5497Workaround(activity);
            }
        }
        return mInstance;
    }

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();

        _globalListener = new ViewTreeObserver.OnGlobalLayoutListener()
        {

            @Override
            public void onGlobalLayout()
            {
                 possiblyResizeChildOfContent();
            }
        };
    }

    public void setListener()
    {
         mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(_globalListener);
    }

    public void removeListener()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mChildOfContent.getViewTreeObserver().removeOnGlobalLayoutListener(_globalListener);
        } else {
            mChildOfContent.getViewTreeObserver().removeGlobalOnLayoutListener(_globalListener);
        }
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    } 
}

私の編集テキストが配置されているクラスを使用します

@Override
public void onStart()
{
    super.onStart();
    AndroidBug5497Workaround.getInstance(getActivity()).setListener();
}

@Override
public void onStop()
{
    super.onStop();
    AndroidBug5497Workaround.getInstance(getActivity()).removeListener();
}

7

android:fitsSystemWindows="true"レイアウトに追加すると、このレイアウトのサイズが変更されます。


それは私のためにそれを解決したものです。さらに、正しいビューに設定するようにしてください。ステータスバーの下にあるはずの背景がある場合は、そこに設定せず、内部のレイアウトに設定します。おそらくEditTextビューなどは、2番目のレイアウトの中にあるはずです。さらにわかりやすくなるので、この講演もご覧ください。youtube.com
Stan

私のためにも働いた。@Stanコメントのおかげで、アクティビティ/フラグメントレイアウトではなく、ViewPagerにその属性を配置するFULLSCREENテーマでも機能させることができました。
marcouberti

5

FullScreenで動作させるには:

イオンキーボードプラグインを使用します。これにより、キーボードが表示されたり消えたりするタイミングを確認できます。

OnDeviceReadyは、次のイベントリスナーを追加します。

// Allow Screen to Move Up when Keyboard is Present
window.addEventListener('native.keyboardshow', onKeyboardShow);
// Reset Screen after Keyboard hides
window.addEventListener('native.keyboardhide', onKeyboardHide);

ロジック:

function onKeyboardShow(e) {
    // Get Focused Element
    var thisElement = $(':focus');
    // Get input size
    var i = thisElement.height();
    // Get Window Height
    var h = $(window).height()
    // Get Keyboard Height
    var kH = e.keyboardHeight
    // Get Focused Element Top Offset
    var eH = thisElement.offset().top;
    // Top of Input should still be visible (30 = Fixed Header)
    var vS = h - kH;
    i = i > vS ? (vS - 30) : i;
    // Get Difference
    var diff = (vS - eH - i);
    if (diff < 0) {
        var parent = $('.myOuter-xs.myOuter-md');
        // Add Padding
        var marginTop = parseInt(parent.css('marginTop')) + diff - 25;
        parent.css('marginTop', marginTop + 'px');
    }
}

function onKeyboardHide(e) {
  // Remove All Style Attributes from Parent Div
  $('.myOuter-xs.myOuter-md').removeAttr('style');
}

基本的に、それらの差がマイナスの場合、それはキーボードが入力をカバーしているピクセルの量です。したがって、これによって親divを調整すると、それを打ち消すはずです。

ロジックにタイムアウトを追加すると、300ミリ秒でパフォーマンスが最適化されます(これにより、キーボード時間が表示されるようになります)


3

ジョセフジョンソンのクラスを試してみましたが、うまくいきましたが、自分のニーズを完全には満たしていませんでした。android:windowSoftInputMode = "adjustResize"をエミュレートするのではなく、android:windowSoftInputMode = "adjustPan"をエミュレートする必要がありました。

これをフルスクリーンのウェブビューに使用しています。コンテンツビューを正しい位置にパンするには、フォーカスがあり、キーボード入力を受け取っているページ要素の位置に関する詳細を提供するJavaScriptインターフェイスを使用する必要があります。これらの詳細は省略しましたが、Joseph Johnsonのクラスを書き直しました。それはあなたがカスタムパン対彼のサイズ変更を実装するための非常に強固な基盤を提供します。

package some.package.name;

import some.package.name.JavaScriptObject;

import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

//-------------------------------------------------------
// ActivityPanner Class
//
// Convenience class to handle Activity attributes bug.
// Use this class instead of windowSoftInputMode="adjustPan".
//
// To implement, call enable() and pass a reference
// to an Activity which already has its content view set.
// Example:
//      setContentView( R.layout.someview );
//      ActivityPanner.enable( this );
//-------------------------------------------------------
//
// Notes:
//
// The standard method for handling screen panning
// when the virtual keyboard appears is to set an activity
// attribute in the manifest.
// Example:
// <activity
//      ...
//      android:windowSoftInputMode="adjustPan"
//      ... >
// Unfortunately, this is ignored when using the fullscreen attribute:
//      android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
//
//-------------------------------------------------------
public class ActivityPanner {

    private View contentView_;
    private int priorVisibleHeight_;

    public static void enable( Activity activity ) {
        new ActivityPanner( activity );
    }

    private ActivityPanner( Activity activity ) {
        FrameLayout content = (FrameLayout)
            activity.findViewById( android.R.id.content );
        contentView_ = content.getChildAt( 0 );
        contentView_.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                public void onGlobalLayout() { panAsNeeded(); }
        });
    }

    private void panAsNeeded() {

        // Get current visible height
        int currentVisibleHeight = visibleHeight();

        // Determine if visible height changed
        if( currentVisibleHeight != priorVisibleHeight_ ) {

            // Determine if keyboard visiblity changed
            int screenHeight =
                contentView_.getRootView().getHeight();
            int coveredHeight =
                screenHeight - currentVisibleHeight;
            if( coveredHeight > (screenHeight/4) ) {
                // Keyboard probably just became visible

                // Get the current focus elements top & bottom
                // using a ratio to convert the values
                // to the native scale.
                float ratio = (float) screenHeight / viewPortHeight();
                int elTop = focusElementTop( ratio );
                int elBottom = focusElementBottom( ratio );

                // Determine the amount of the focus element covered
                // by the keyboard
                int elPixelsCovered = elBottom - currentVisibleHeight;

                // If any amount is covered
                if( elPixelsCovered > 0 ) {

                    // Pan by the amount of coverage
                    int panUpPixels = elPixelsCovered;

                    // Prevent panning so much the top of the element
                    // becomes hidden
                    panUpPixels = ( panUpPixels > elTop ?
                                    elTop : panUpPixels );

                    // Prevent panning more than the keyboard height
                    // (which produces an empty gap in the screen)
                    panUpPixels = ( panUpPixels > coveredHeight ?
                                    coveredHeight : panUpPixels );

                    // Pan up
                    contentView_.setY( -panUpPixels );
                }
            }
            else {
                // Keyboard probably just became hidden

                // Reset pan
                contentView_.setY( 0 );
            }

            // Save usabale height for the next comparison
            priorVisibleHeight_ = currentVisibleHeight;
        }
    }

    private int visibleHeight() {
        Rect r = new Rect();
        contentView_.getWindowVisibleDisplayFrame( r );
        return r.bottom - r.top;
    }

    // Customize this as needed...
    private int viewPortHeight() { return JavaScriptObject.viewPortHeight(); }
    private int focusElementTop( final float ratio ) {
        return (int) (ratio * JavaScriptObject.focusElementTop());
    }
    private int focusElementBottom( final float ratio ) {
        return (int) (ratio * JavaScriptObject.focusElementBottom());
    }

}

必要なようですが、完全なサンプルを追加していただけませんか?あなたの仕事に感謝します!
vilicvane 2015年

プロジェクト全体を投稿するつもりはありませんでした。私が提供したものは、完全に機能するソリューションに至るまでの非常に長い道のりをあなたにもたらすでしょう。自分で定義する必要があるもの:「JavaScriptObject」クラスを作成し、それをjsインターフェースとしてWebビューに挿入します(Webビューのドキュメントで確認してください)。包括的な方法でWebViewを使用するものを作成する場合は、すでにそれを行っている可能性が十分にあります。JavaScriptをWebビューに追加して、フォーカスイベントをリッスンし、フォーカス要素の配置に関するデータをJavaScriptObjectクラスにフィードします。
BuvinJ 2016年

2

確かに、ソフトキーボードの外観は、モードでActivitywindowSoftInputModeを選択しても、まったく影響を受けないようFullScreenです。

このプロパティに関するドキュメントはあまりありませんでしたが、このFullScreenモードはソフトキーボードをあまり使用する必要のないゲームアプリケーション用に設計されたものだと思います。あなたがソフトキーボードを介したユーザー操作を必要とするアクティビティの場合は、フルスクリーン以外のテーマの使用を再検討してください。NoTitleBarテーマを使用してTitleBarをオフにすることができます。通知バーを非表示にしたいのはなぜですか?


2

そのままにしてくださいandroid:windowSoftInputMode="adjustResize"。なぜなら"adjustResize""adjustPan"(およびウィンドウ調整モードは、adjustResizeまたはadjustPanのいずれかで指定されます。常にどちらか一方を指定することを強くお勧めします)。あなたはそれをここで見つけることができます:http//developer.android.com/resources/articles/on-screen-inputs.html

それは私にとって完璧に機能します。


問題ありません...あなたのXMLも試しました。またworks..m OSのバージョン2.2を使用して、この1
バラジKhadake

全画面モードのみで試してみました... Nexus OneとNexus Sでテストしています...正常に動作します。
Balaji Khadake、2011

1
Galaxy S、HTC wildfire、HTC Hero、Motorola Deify、Sony XPeriaで試しました。単一のデバイスでは動作しません。
Vineet Shukla、2011


2

私は現在このアプローチを使用しており、それは魅力のように機能します。トリックは、21の上下のさまざまなメソッドからキーボードの高さを取得し、それをアクティビティのルートビューの下部のパディングとして使用することです。私はあなたのレイアウトが上部のパディングを必要としないと仮定しました(ステータスバーの下に行きます)が必要な場合は、私の回答を更新するように通知してください。

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RelativeLayout mainLayout = findViewById(R.id.main_layout);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            ViewCompat.setOnApplyWindowInsetsListener(mainLayout , new OnApplyWindowInsetsListener() {
                @Override
                public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
                    v.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
                    return insets;
                }
            });
        } else {
            View decorView = getWindow().getDecorView();
            final View contentView = mainLayout;
            decorView.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.
                    decorView.getWindowVisibleDisplayFrame(r);

                    //get screen height and calculate the difference with the useable area from the r
                    int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
                    int diff = height - r.bottom;

                    //if it could be a keyboard add the padding to the view
                    if (diff != 0) {
                        // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                        //check if the padding is 0 (if yes set the padding for the keyboard)
                        if (contentView.getPaddingBottom() != diff) {
                            //set the padding of the contentView for the keyboard
                            contentView.setPadding(0, 0, 0, diff);
                        }
                    } else {
                        //check if the padding is != 0 (if yes reset the padding)
                        if (contentView.getPaddingBottom() != 0) {
                            //reset the padding of the contentView
                            contentView.setPadding(0, 0, 0, 0);
                        }
                    }
                }
            });
        }
    }
...
}

ルートビューをIDでアドレス指定することを忘れないでください。

activity_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

それが誰かを助けることを願っています。


1
理解できません。なぜこの回答がまだ上位にないのですか。他のものはグリッチ、フラッシュですが、これは特に5以上のAPIがある場合は素晴らしいです。
アントンシュクレンコ

1

android:windowSoftInputMode="adjustResize|stateHiddenAdjustPanを使用するときにのみ使用し、サイズ変更プロパティを無効にします


私もそれを使用しました。フルスクリーンモードで実行していて、どのデバイスでテストしていますか?
Vineet Shukla、2011

HTC NEXUS one、ok i hvnt add full screen
Mohammed Azharuddin Shaikh

getWindow()。requestFeature(Window.FEATURE_NO_TITLE);を使用できますか?代わりにテーマを使用してonCreate()?
Mohammed Azharuddin Shaikh 2011

10
上記のコードは全画面表示なしで正常に機能していますが、xmlまたはコードから全画面表示を追加しています...機能していません...質問をよく読んでください。
Vineet Shukla 2011

1

Joseph Johnsonを使用してAndroidBug5497Workaroundクラスを作成しましたが、ソフトキーボードとビューの間に黒いスペースができました。私はこのリンクGreg Ennisを参照しました。上記のいくつかの変更を行った後、これが私の最終的な作業コードです。

 public class SignUpActivity extends Activity {

 private RelativeLayout rlRootView; // this is my root layout
 private View rootView;
 private ViewGroup contentContainer;
 private ViewTreeObserver viewTreeObserver;
 private ViewTreeObserver.OnGlobalLayoutListener listener;
 private Rect contentAreaOfWindowBounds = new Rect();
 private FrameLayout.LayoutParams rootViewLayout;
 private int usableHeightPrevious = 0;

 private View mDecorView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_sign_up);
  mDecorView = getWindow().getDecorView();
  contentContainer =
   (ViewGroup) this.findViewById(android.R.id.content);

  listener = new OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
    possiblyResizeChildOfContent();
   }
  };

  rootView = contentContainer.getChildAt(0);
  rootViewLayout = (FrameLayout.LayoutParams)
  rootView.getLayoutParams();

  rlRootView = (RelativeLayout) findViewById(R.id.rlRootView);


  rlRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
    int heightDiff = rlRootView.getRootView().getHeight() - rlRootView.getHeight();
    if (heightDiff > Util.dpToPx(SignUpActivity.this, 200)) {
     // if more than 200 dp, it's probably a keyboard...
     //  Logger.info("Soft Key Board ", "Key board is open");

    } else {
     Logger.info("Soft Key Board ", "Key board is CLOSED");

     hideSystemUI();
    }
   }
  });
 }

 // This snippet hides the system bars.
 protected void hideSystemUI() {
  // Set the IMMERSIVE flag.
  // Set the content to appear under the system bars so that the 
  content
  // doesn't resize when the system bars hide and show.
  mDecorView.setSystemUiVisibility(
   View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
 }
 @Override
 protected void onPause() {
  super.onPause();
  if (viewTreeObserver.isAlive()) {
   viewTreeObserver.removeOnGlobalLayoutListener(listener);
  }
 }

 @Override
 protected void onResume() {
  super.onResume();
  if (viewTreeObserver == null || !viewTreeObserver.isAlive()) {
   viewTreeObserver = rootView.getViewTreeObserver();
  }
  viewTreeObserver.addOnGlobalLayoutListener(listener);
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  rootView = null;
  contentContainer = null;
  viewTreeObserver = null;
 }
 private void possiblyResizeChildOfContent() {
  contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);

  int usableHeightNow = contentAreaOfWindowBounds.height();

  if (usableHeightNow != usableHeightPrevious) {
   rootViewLayout.height = usableHeightNow;
   rootView.layout(contentAreaOfWindowBounds.left,
    contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
   rootView.requestLayout();

   usableHeightPrevious = usableHeightNow;
  } else {

   this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
  }
 }
}

1

https://stackoverflow.com/a/19494006/1815624に基づいており、それを実現したい...

更新されたアイデア


からの回答を組み合わせる

関連コード:

        if (heightDifference > (usableHeightSansKeyboard / 4)) {

            // keyboard probably just became visible
            frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        } else {

            // keyboard probably just became hidden
            if(usableHeightPrevious != 0) {
                frameLayoutParams.height = usableHeightSansKeyboard;
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

            }

https://github.com/CrandellWS/AndroidBug5497Workaround/blob/master/AndroidBug5497Workaround.javaの完全なソース

古い考え

キーボードを開く前にコンテナの高さの静的な値を作成するusableHeightSansKeyboard - heightDifferenceキーボードが開いたときにコンテナの高さを設定し、閉じたときに保存されていた値に戻す

if (heightDifference > (usableHeightSansKeyboard / 4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
                int mStatusHeight = getStatusBarHeight();
                frameLayoutParams.topMargin = mStatusHeight;
                ((MainActivity)activity).setMyMainHeight(usableHeightSansKeyboard - heightDifference);

                if(BuildConfig.DEBUG){
                    Log.v("aBug5497", "keyboard probably just became visible");
                }
            } else {
                // keyboard probably just became hidden
                if(usableHeightPrevious != 0) {
                    frameLayoutParams.height = usableHeightSansKeyboard;
                    ((MainActivity)activity).setMyMainHeight();    
                }
                frameLayoutParams.topMargin = 0;

                if(BuildConfig.DEBUG){
                    Log.v("aBug5497", "keyboard probably just became hidden");
                }
            }

MainActivityのメソッド

public void setMyMainHeight(final int myMainHeight) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            ConstraintLayout.LayoutParams rLparams =  (ConstraintLayout.LayoutParams) myContainer.getLayoutParams();
            rLparams.height = myMainHeight;

            myContainer.setLayoutParams(rLparams);
        }

    });

}

int mainHeight = 0;
public void setMyMainHeight() {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            ConstraintLayout.LayoutParams rLparams =  (ConstraintLayout.LayoutParams) myContainer.getLayoutParams();
            rLparams.height = mainHeight;

            myContainer.setLayoutParams(rLparams);
        }

    });

}

コンテナXMLの例

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
        <android.support.constraint.ConstraintLayout
            android:id="@+id/my_container"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintHeight_percent=".8">

同様に、必要に応じてマージンを追加できます...

別の考慮事項は、パディングの使用です。この例は、次の場所にあります。

https://github.com/mikepenz/MaterialDrawer/issues/95#issuecomment-80519589


1

1)KeyboardHeightHelperを作成します。

public class KeyboardHeightHelper {

    private final View decorView;
    private int lastKeyboardHeight = -1;

    public KeyboardHeightHelper(Activity activity, View activityRootView, OnKeyboardHeightChangeListener listener) {
        this.decorView = activity.getWindow().getDecorView();
        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
            int keyboardHeight = getKeyboardHeight();
            if (lastKeyboardHeight != keyboardHeight) {
                lastKeyboardHeight = keyboardHeight;
                listener.onKeyboardHeightChange(keyboardHeight);
            }
        });
    }

    private int getKeyboardHeight() {
        Rect rect = new Rect();
        decorView.getWindowVisibleDisplayFrame(rect);
        return decorView.getHeight() - rect.bottom;
    }

    public interface OnKeyboardHeightChangeListener {
        void onKeyboardHeightChange(int keyboardHeight);
    }
}

2)アクティビティを全画面表示にします。

activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

3)キーボードの高さの変化を確認し、ビューの下部にパディングを追加します。

View rootView = activity.findViewById(R.id.root); // your root view or any other you want to resize
KeyboardHeightHelper effectiveHeightHelper = new KeyboardHeightHelper(
        activity, 
        rootView,
        keyboardHeight -> rootView.setPadding(0, 0, 0, keyboardHeight));

したがって、キーボードが画面に表示されるたびに、ビューの下部のパディングが変更され、コンテンツが再配置されます。


0

ボトムバーをビューの下部に固定したいのですが、キーボードが表示されている場合、キーボードの上に移動する必要がありますよね?

あなたはこのコードスニペットを試すことができます:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    ...>

    <RelativeLayout
        android:id="@+id/RelativeLayoutTopBar"
    ...>
    </RelativeLayout>

    <LinearLayout
        android:id="@+id/LinearLayoutBottomBar"
        android:layout_alignParentBottom = true
        ...>
    </LinearLayout>

    <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="390dp"
    android:orientation="vertical" 
    android:layout_above="@+id/LinearLayoutBottomBar"
    android:layout_below="@+id/RelativeLayoutTopBar"> 

    <ScrollView 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="10dp"
        android:id="@+id/ScrollViewBackground">

            ...

        </ScrollView>
     </LinearLayout>
  </RelativeLayout>

BottomBarはビューの下部に固定され、ScrollViewを含むLinearLayoutは、上部/下部バーとキーボードが表示された後、ビューの残りの部分を取得します。うまくいくかどうか教えてください。


1
それは私のアプリで数回働いたので非常に奇妙です。ちなみに、RelativeLayoutには方向がないため、コードでこれらの属性を削除できます。コードスニペットをandroid:layout_below = "@ + id / scoringContainerView"の行に切り詰めることができることを認識しました。これをScrollViewに追加する必要があります
banzai86

全画面表示?上部にレイアウトがないということですか?
banzai86 2011

無.....私は、デバイスのバッテリ寿命、接続性を示すいかなるステータスバーを意味しないなど...
Vineetシュクラ

いいえ、ステータスバーはアプリに表示されます。レイアウトの順序を変更してみてください。つまり、レイアウトのコードをボタン付きで他のコードの上に置いてから、もう一度やり直してください。おそらく、layout_belowを使用するために最初にそれらを定義する必要があるかもしれません
banzai86

1
質問を注意深くお読みください......
フルスクリーン

0

ジョセフ、回答ありがとうございます。ただし、場合によってはメソッドResizeChildOfContent()で、部分

else {
            // keyboard probably just became hidden
            frameLayoutParams.height = usableHeightSansKeyboard;
        }

視界の下部が隠れてしまったので、私にはうまくいかなかった。したがって、グローバル変数restoreHeightを取得する必要があり、コンストラクターで最後の行を挿入しました

restoreHeight = frameLayoutParams.height;

そして、私は前に述べた部分を

else {
            // keyboard probably just became hidden
            frameLayoutParams.height = restoreHeight;
        }

しかし、なぜあなたのコードが私にとってうまくいかなかったのか私にはわかりません。誰かがこれに光を当てることができれば、それは大きな助けになるでしょう。


0

ステータスバーを非表示にするためにフルスクリーンモードのみを使用していました。ただし、キーボードが表示されているときにアプリのサイズを変更したい。他のすべての解決策(投稿の年齢が原因である可能性が高い)は複雑であるか、使用することが不可能でした(PhoneGapビルドの袋のJavaコードの変更を避けたい)。

全画面を使用する代わりに、Androidの設定を全画面以外に変更しました。

            <preference name="fullscreen" value="false" />

そしてcordova-plugin-statusbar、コマンドライン経由でを追加しました:

cordova plugin add cordova-plugin-statusbar

アプリが読み込まれたら、プラグインのメソッドを呼び出して、次のように自分自身を非表示にします。

    if (window.cordova && window.cordova.platformId == 'android' && window.StatusBar)
        window.StatusBar.hide();

これは魅力のように機能します。本当の欠点は、アプリが読み込まれている間、ステータスバーがはっきりと表示されることです。私のニーズでは、それは問題ではありませんでした。


0

私はstackOverflowから可能なすべての答えを試しましたが、1週間の長い検索の後に最終的に解決しました。私は座標レイアウトを使用しましたが、linearLayoutでこれを変更し、問題を修正しました。座標レイアウトにバグや何か間違いがあるのか​​もしれません。


0

私は、Joseph JohnsonやJohan Stuytsを含む多くの解決策を試しました。しかし、結果として、一部のデバイス(Lenovo s820など)では、コンテンツとキーボードの間に空白ができました。だから私は彼らのコードにいくつかの変更を加え、最終的に実用的な解決策を得ました。

キーボードが表示されているときにコンテンツの上部にマージンを追加することに基づく私の考え。

contentContainer.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);
    int usableHeightNow = contentAreaOfWindowBounds.height();

    if (usableHeightNow != usableHeightPrevious) {

        int difference = usableHeightNow - usableHeightPrevious;

        if (difference < 0 && difference < -150) {
            keyboardShowed = true;
            rootViewLayout.topMargin -= difference + 30;
            rootViewLayout.bottomMargin += 30;
        }
        else if (difference < 0 && difference > -150){
            rootViewLayout.topMargin -= difference + 30;
        }
        else if (difference > 0 && difference > 150) {
            keyboardShowed = false;
            rootViewLayout.topMargin = 0;
            rootViewLayout.bottomMargin = 0;
        }

        rootView.requestLayout();

        Log.e("Bug Workaround", "Difference: " + difference);

        usableHeightPrevious = usableHeightNow;
}

ご覧のとおり、画面上部とコンテンツゾーンの間に余白のある小さな空白があるため、差に30ピクセルを追加します。そして、どこに表示されるのかわからないので、マージンを小さくすることにしましたが、今では必要な方法で正確に機能します。


0

今日、フルスクリーンのAdjustResizeが機能しない問題は、Android SDKで実際に発生しています。

私が見つけた回答から:
解決策 -しかし、解決策はこれを画像の問題に示しています:

私が解決策を見つけて不要なアクションを1つ削除した場合:

this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

だから、Kotlinの私の修正済みソリューションコードを参照してください。

class AndroidBug5497Workaround constructor(val activity: Activity) {

    private val content = activity.findViewById<View>(android.R.id.content) as FrameLayout

    private val mChildOfContent = content.getChildAt(0)
    private var usableHeightPrevious: Int = 0
    private val contentContainer = activity.findViewById(android.R.id.content) as ViewGroup
    private val rootView = contentContainer.getChildAt(0)
    private val rootViewLayout = rootView.layoutParams as FrameLayout.LayoutParams

    private val listener = {
        possiblyResizeChildOfContent()
    }

    fun addListener() {
        mChildOfContent.apply {
            viewTreeObserver.addOnGlobalLayoutListener(listener)

        }
    }

    fun removeListener() {
        mChildOfContent.apply {
            viewTreeObserver.removeOnGlobalLayoutListener(listener)
        }
    }

    private fun possiblyResizeChildOfContent() {
        val contentAreaOfWindowBounds = Rect()
        mChildOfContent.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds)
        val usableHeightNow = contentAreaOfWindowBounds.height()

        if (usableHeightNow != usableHeightPrevious) {
            rootViewLayout.height = usableHeightNow
            rootView.layout(contentAreaOfWindowBounds.left,
                    contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
            mChildOfContent.requestLayout()
            usableHeightPrevious = usableHeightNow
        }
    }
}

私のバグ修正実装コード:

 class LeaveDetailActivity : BaseActivity(){

    private val keyBoardBugWorkaround by lazy {
        AndroidBug5497Workaround(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    }

    override fun onResume() {
        keyBoardBugWorkaround.addListener()
        super.onResume()
    }

    override fun onPause() {
        keyBoardBugWorkaround.removeListener()
        super.onPause()
    }
}

0

使用しないでください:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

うまくいかないからです。その代わりに、次を使用します。

fun setFullScreen(fullScreen: Boolean) {
        val decorView = getWindow().getDecorView()
        val uiOptions : Int
        if(fullScreen){
            uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN // this hide statusBar
            toolbar.visibility = View.GONE // if you use toolbar
            tabs.visibility = View.GONE // if you use tabLayout
        } else {
            uiOptions = View.SYSTEM_UI_FLAG_VISIBLE // this show statusBar
            toolbar.visibility = View.VISIBLE
            tabs.visibility = View.VISIBLE
        }
        decorView.setSystemUiVisibility(uiOptions)
    }

-1

私の場合、CrosdwalkをCordovaアプリケーションに追加すると、この問題が発生し始めました。私のアプリはフルスクリーンとandroid:windowSoftInputMode = "adjustPan"で使用されていません。

私はすでにアプリケーションにイオンキーボードプラグインを持っているので、キーボードのアップまたはダウンを簡単に検出できました。

// Listen for events to when the keyboard is opened and closed
window.addEventListener("native.keyboardshow", keyboardUp, false);
window.addEventListener('native.keyboardhide', keyboardDown, false);

function keyboardUp()
{
    $('html').addClass('keyboardUp');
}

function keyboardDown()
{
    $('html').removeClass('keyboardUp');
}

私は上記の修正をすべて試しましたが、私のためにそれをやった単純な行はこのちょっとしたCSSでした:

&.keyboardUp {
        overflow-y: scroll;
}

これが私がこれに費やした数日を節約してくれることを願っています。:)


Cordovaとandroid:windowSoftInputMode = "adjustPan"で横断歩道を使用しています。ただし、機能していません。クラスがhtml要素に追加されているのがわかりますが、CSSは画面に影響を与えません。画面の移動を可能にする他の設定はありますか?
darewreck

動作させるには、add transform:translateY(0px)を設定する必要があります。ただし、スクロールはまったく機能しません。何か案は?
darewreck 2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.