web-dev-qa-db-ja.com

Android-キーボードの上にBottomSheetDialogFragmentを表示

ユーザーが情報を入力できるように、いくつかのBottomSheetDialogFragmentフィールドを含むEditTextを表示しようとしています。キーボードの真上に表示したいのですが、中身が隠れてしまいます。

これがBottomSheetDialogFragmentを呼び出すとどうなりますか。これは_Card Number_ EditTextを選択しているが、他のコンテンツをカバーしていることがわかります。

BottomSheetDialogFragment covering up content

理想的には、これが私が探しているものであり、EditTextsとビューのパディングの両方が表示されます。

BottomSheetDialogFragment not covering up content

私はwindowSoftInputModeを中心にさまざまな解決策を試しましたが、何も機能しないようです。親adjustResizeと実際のActivityBottomSheetDialogFragmentに設定しました

dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)

また、レイアウトを変更して、FrameLayoutからScrollViewからCoordinatorLayoutに変更して、レイアウトの位置に影響があるかどうかを確認しました、しかし何も動作しないようです。

誰かがこれを達成する方法を知っているなら、それは大いに感謝されます、ありがとう。

15
Advice-Dog

おそらく遅い回答ですが、おそらく役立つでしょう。

他には何もうまくいきませんでした。しかし、このソリューションは機能しています

内側のスタイル:

<style>  // main theme
    <item name="bottomSheetDialogTheme">@style/BottomSheetDialogTheme</item>
    ........ // rest of the code
</style>

<style name="BottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/AppModalStyle</item>
    <item name="Android:windowIsFloating">false</item>
    <item name="Android:windowSoftInputMode">adjustResize</item>
    <item name="Android:statusBarColor">@Android:color/transparent</item> 
</style>

ここに Android:windowIsFloatingはfalseである必要があります&Android:windowSoftInputModeadjustResizeでなければなりません

<style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
    <item name="Android:background">@drawable/rounded_corner_dialog</item>
</style>

NestedScrollView内でレイアウトをラップする

<androidx.core.widget.NestedScrollView
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content">

     <--Rest of the layout-->
</androidx.core.widget.NestedScrollView>

一部のデバイスでは、このソリューションでは不十分でした。これをコードに追加すると、私の問題は完全に解決されました。

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    dialog?.setOnShowListener {
        val dialog = it as BottomSheetDialog
        val bottomSheet = dialog.findViewById<View>(R.id.design_bottom_sheet)
        bottomSheet?.let { sheet ->
            dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
            sheet.parent.parent.requestLayout()
        }
    }
}

このBottomSheetDialogFragmentを試してください:

import Android.graphics.Rect; 
import Android.os.Bundle;
import Android.support.annotation.NonNull;
import Android.support.annotation.Nullable;
import Android.support.design.widget.BottomSheetBehavior;
import Android.support.design.widget.BottomSheetDialog;
import Android.support.design.widget.BottomSheetDialogFragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.view.WindowManager;

public class TestBottomSheetDialog extends BottomSheetDialogFragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View fragmentView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_bottom_sheet, container, false);
        if (getDialog().getWindow() != null) {
           getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        }
        if (getActivity() != null) {
            View decorView = getActivity().getWindow().getDecorView();
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
                Rect displayFrame = new Rect();
                decorView.getWindowVisibleDisplayFrame(displayFrame);
                int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
                int heightDifference = height - displayFrame.bottom;
                if (heightDifference != 0) {
                    if (fragmentView.getPaddingBottom() != heightDifference) {
                        fragmentView.setPadding(0, 0, 0, heightDifference);
                    }
                } else {
                    if (fragmentView.getPaddingBottom() != 0) {
                        fragmentView.setPadding(0, 0, 0, 0);
                    }
                }
            });
        }
        getDialog().setOnShowListener(dialog -> {
            BottomSheetDialog d = (BottomSheetDialog) dialog;
            View bottomSheetInternal = d.findViewById(Android.support.design.R.id.design_bottom_sheet);
            if (bottomSheetInternal == null) return;
             BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
        });
        return fragmentView;
    }
}
1
Vitali

次の手順は、問題の解決に役立つ場合があります。

まず、XMLファイルのEditTextに次の行を追加します

Android:imeOptions="actionSend|flagNoEnterAction"

例えば:

<EditText
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:inputType="number"
    Android:hint="Card number"
    Android:imeOptions="actionSend|flagNoEnterAction"/>

次に、AndroidManifest.xmlファイルのアクティビティタグに次の行を追加します

Android:windowSoftInputMode="stateVisible|adjustResize"

例えば:

<activity Android:name=".stack.MainActivity"
    Android:windowSoftInputMode="stateVisible|adjustResize">
    <intent-filter>
        <action Android:name="Android.intent.action.MAIN" />

        <category Android:name="Android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

オンスクリーン入力メソッドの詳細については、 here を参照してください。

1

キーボードが開いているときにダイアログの高さを最後に変更し、閉じるときに通常のサイズに変更しました。

KeyboardVisibilityEventライブラリ: https://Android-arsenal.com/details/1/2519

  KeyboardVisibilityEvent.setEventListener(activity) { isOpen ->
            setDialogHeight(isOpen)
  }

2.0.0のサポート最小SDKバージョンは14です。

キーボードが開いたら、ダイアログの高さを80%に設定します。

    /**
     * Changes size of dialog based on keyboard visibility state
     */
    private fun setDialogHeight(expanded: Boolean) {
        val dialog = dialog as BottomSheetDialog?
        val bottomSheet =
            dialog!!.findViewById<View>(com.google.Android.material.R.id.design_bottom_sheet) as FrameLayout?
        val behavior = BottomSheetBehavior.from(bottomSheet!!)

        val displayMetrics = activity!!.resources.displayMetrics

        val width = displayMetrics.widthPixels
        val height = displayMetrics.heightPixels

        val maxHeight = (height * 0.88).toInt()

        behavior.peekHeight = if (expanded) maxHeight else -1
    }
1
Morteza Rastgoo

レイアウトの高さを大きくする必要がありました。 ボトムシートダイアログフラグメントのデフォルトの高さを変更する方法? のプログラムによる方法は役に立たなかったため、レイアウトを変更しました。

<Android.support.constraint.ConstraintLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    >

    <View
        Android:id="@+id/top_space"
        Android:layout_width="match_parent"
        Android:layout_height="10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <!-- Other views -->

    <View
        Android:id="@+id/bottom_space"
        Android:layout_width="match_parent"
        Android:layout_height="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/button"
        app:layout_constraintVertical_weight="1"
        />

</Android.support.constraint.ConstraintLayout>
0
CoolMind

仮想キーボードにパディングを追加することは、Android OS自体ではサポートされていませんが、ハッキングする方法があります。

1つの方法は、edittextのフォーカスをリッスンして、ScrollViewをもう少しスクロールすることです。

edittext.setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus)
             scrollView.scrollBy(0, 100);

    });

私が言ったように、この方法はハッキーであり、推奨されません。

別の方法(レイアウトに依存し、機能させる場合はより良い)は、アクティビティのwindowSoftInputModeadjustPanまたはadjustResize(レイアウトに依存)に設定することです。 AndroidManifest.xml内。

0
Adib Faramarzi