10

所以在过去的几年里,这个问题已经在这里被问过几次了,没有一个解决方案对我有用。

问题是,当我AdjustPan用来移动软键盘时,它隐藏了EditText如下部分:

在此处输入图像描述

我尝试的解决方案是:

解决方案 1 (2011)

解决方案 2 (2014)

解决方案 3 (2013)

大多数答案都包括使用AdjustPan/AdjustResize,所以我只想说它们都没有提供所需的解决方案(EditText打开键盘时显示整体)。

我在想也许在 2019 年有一个可行的解决方案来解决这个问题。

此布局的 xml 是:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
    android:background="@color/colorWhite"
    tools:context=".ChatActivity">


    <androidx.appcompat.widget.ActionMenuView
        android:id="@+id/actionbar"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/colorGrayBox"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.1"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    </androidx.appcompat.widget.ActionMenuView>

    <TextView
        android:id="@+id/tv_This"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginTop="16dp"
        android:fontFamily="@font/open_sans"
        android:text="@string/ActivityChat_This"
        android:textSize="12sp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/actionbar" />

    <View
        android:id="@+id/v_Line"
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="24dp"
        android:layout_marginTop="16dp"
        android:layout_marginRight="24dp"
        android:background="@color/colorLightGray"
        app:layout_constraintTop_toBottomOf="@+id/tv_This" />

    <androidx.cardview.widget.CardView
        android:id="@+id/imagecard"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginStart="16dp"
        app:cardCornerRadius="20dp"
        app:layout_constraintBottom_toBottomOf="@+id/actionbar"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageButton
            android:id="@+id/ivPersonPic"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:background="@null" />

    </androidx.cardview.widget.CardView>

    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:fontFamily="@font/assistant_bold"
        android:textColor="@color/colorLightPurple"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/actionbar"
        app:layout_constraintStart_toEndOf="@+id/imagecard"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_Messages"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toTopOf="@+id/constraint2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/v_Line"/>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraint2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
        app:layout_constraintHeight_percent="0.1">

        <EditText
            android:id="@+id/et_Message"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginStart="12dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:background="@drawable/et_rounded"
            android:fontFamily="@font/assistant"
            android:gravity="center_vertical"
            android:hint="@string/ActivityChat_Type"
            android:inputType="textMultiLine|textPersonName"
            android:paddingEnd="32dp"
            android:paddingStart="32dp"
            android:textSize="16sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintWidth_percent="0.85" />

        <ImageButton
            android:id="@+id/ib_Send"
            style="?android:borderlessButtonStyle"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            android:adjustViewBounds="true"
            android:src="@drawable/ic_chats_send"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintWidth_percent="0.1" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:itemBackground="@color/colorWhite"
        app:itemIconTint="@drawable/btm_nav"
        app:itemTextColor="@drawable/btm_nav"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.08"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/menu_btm_nav" />

</androidx.constraintlayout.widget.ConstraintLayout>
4

11 回答 11

5

AndroidManifest.xml试试这个,在你的活动中添加这个代码

android:windowSoftInputMode="adjustPan" 

将以下内容添加到xml文件的根布局中

android:fitsSystemWindows="true"
于 2020-02-13T06:40:03.150 回答
2

首先将ScrollView添加到您的 XML 中,并将以下行添加到您使用此搜索EditText的活动标记中的 AndroidManiFest.xml 中。

android:windowSoftInputMode="stateAlwaysHidden|adjustResize|adjustPan|adjustResize
于 2020-02-12T13:37:13.907 回答
1

我自己在使用键盘时遇到了很多问题,但我更喜欢使用键盘,android:windowSoftInputMode="adjustResize"这样您就可以自己处理更改。您应该将 windowInsetsListener 添加到您的根视图,如果您没有透明导航栏,则systemWindowInsetBottom应该只是键盘。所以你可以只为你感兴趣的容器添加填充。这是我使用的一个例子:

rootContainer.setOnApplyWindowInsetsListener { view, windowInsets ->
    var containerPadding = 0
    if (windowInsets.systemWindowInsetBottom > 0) {
        val bottomBarHeight = bottomBar.bottom - bottomBar.top
        containerPadding = windowInsets.systemWindowInsetBottom - bottomBarHeight
    }

    if (containerPadding < 0) {
        containerPadding = 0
    }

    contentView.bottomPadding = containerPadding

    return@setOnApplyWindowInsetsListener windowInsets.replaceSystemWindowInsets(windowInsets.systemWindowInsetLeft, windowInsets.systemWindowInsetTop, windowInsets.systemWindowInsetRight, 0)
}

这样,您可以将bottomBar 上方的容器向上移动(其中有您EditText的)。

对我来说,这是迄今为止我找到的最佳选择。大多数选项都依赖于 GlobalLayoutListeners 并查看它有多少变化,但这要可靠得多。

于 2020-02-19T09:29:41.793 回答
1

将基本布局包装在 ScrollView 中,设置高度为 match_parent 和 fillViewport 为 true:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

并在清单中:

<activity
    android:name=".YourActivity"
    android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />

将此用作第二种解决方案,在这里我检查键盘出现后布局是否未完全显示,在这种情况下将 sview 滚动 200 像素。代码也有一些注释。

import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.ScrollView;

public class MainActivity extends AppCompatActivity {

    private ScrollView sView;
    private int heightDiff;

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


        sView = findViewById(R.id.scrollView);
        //Here we get the height of soft keyboard by observing changes of the scrollView's height.
        sView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                heightDiff = sView.getRootView().getHeight() - sView.getHeight();
            }
        });


        final EditText editText = findViewById(R.id.et_Message);
        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!isVisibleWhileSoftKeyboardShowing(editText) && hasFocus) {
                    sView.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            sView.smoothScrollBy(0, 200);
                        }
                    }, 500);
                }

            }
        });
    }

    /**
     * check if a view is currently visible in the screen or not
     *
     * @param view
     * @return
     */
    public boolean isVisibleWhileSoftKeyboardShowing(final View view) {
        if (view == null) {
            return false;
        }
        if (!view.isShown()) {
            return false;
        }
        final Rect actualPosition = new Rect();
        view.getGlobalVisibleRect(actualPosition);
        final Rect screen = new Rect(0, 0, getScreenWidth(), getScreenHeight() - heightDiff);
        return actualPosition.intersect(screen);
    }


    /**
     * to get screen width
     *
     * @return
     */
    public static int getScreenWidth() {
        return Resources.getSystem().getDisplayMetrics().widthPixels;
    }

    /**
     * to get screen height
     *
     * @return
     */
    public static int getScreenHeight() {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }
} 
于 2019-10-26T12:59:31.713 回答
0
 <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraint2"

在 ConstraintLayout 中添加填充底部,如 android:paddingBottom="8dp"

从EdittextImageview中删除android:layout_marginBottom="8dp" 即 android:id="@+id/et_Message" 和 android:id="@+id/ib_Send"

然后重新运行

于 2020-02-12T07:20:16.363 回答
0

有一个技巧可以做到这一点:

1-将 EditText 放入 CardView

2- 将 CardView 设置为看起来像 TextEdit

3-将这些属性添加到 EditText

android:paddingBottom="15dp"
android:paddingTop="15dp"
android:background="@android:color/transparent"
于 2021-03-04T14:37:48.697 回答
0

EditText用视图替换TextInputEditText视图并简单地在其底部添加填充,例如:

<com.google.android.material.textfield.TextInputLayout
    ...
    <com.google.android.material.textfield.TextInputEditText
        android:paddingBottom="30dp"
        ...
        android:textSize="15sp"
        android:hint="@string/txt_hint_add_comment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
    />
</com.google.android.material.textfield.TextInputLayout>
于 2021-12-27T11:31:01.910 回答
0

在您的文件中,在标签Layout中添加以下行。Constraint

android:isScrollContainer="true"
于 2020-02-13T08:13:50.430 回答
0

希望这对你有用:-

<Your View>.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {

                Rect r = new Rect();
            screen.getWindowVisibleDisplayFrame(r);
            int screenHeight = screen.getRootView().getHeight();

            // r.bottom is the position above soft keypad or device button.
            // if keypad is shown, the r.bottom is smaller than that before.
            int keypadHeight = screenHeight - r.bottom;

            if (keypadHeight > screenHeight * 0.15) {
            //keyboard is open
            //programatically set margins to your EditText
            }

            else{
            //programatically reset your margins 
            }
        });
于 2020-02-12T09:35:17.170 回答
0

首先,我认为你的布局应该改进,没有必要ConstraintLayout在单个 xml 文件中使用两个,第二个是第一个/主文件的子级。这个视图背后的想法是扁平化你的整个布局,所以作为第一步,我认为你应该摆脱第二个ConstraintLayout.

我创建了一个看起来有点像你的简单布局,以便测试我的实现是否可以工作,所以这里是布局文件:

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <View
        android:layout_width="0dip"
        android:layout_height="0dip"
        app:layout_constraintBottom_toTopOf="@+id/edit_text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/edit_text"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:background="@drawable/rounded"
        android:gravity="center_vertical"
        android:hint="Text"
        android:importantForAutofill="no"
        android:inputType="textMultiLine|textPersonName"
        android:paddingStart="32dip"
        android:paddingEnd="32dip"
        android:textSize="16sp"
        app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view"
        app:layout_constraintEnd_toStartOf="@+id/btn_send"
        app:layout_constraintStart_toStartOf="parent"
        tools:ignore="HardcodedText" />

    <Button
        android:id="@+id/btn_send"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_marginStart="12dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:text="SEND"
        app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view"
        app:layout_constraintEnd_toEndOf="parent"
        tools:ignore="HardcodedText" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="#c5c6c7"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

BottomNavigatioView该结构看起来与您的相似,至少带有EditText和 的部分Button。添加android:windowSoftInputMode="adjustPan"Activity包含此布局的其中将给出此结果(在一些设备上测试):

截图01 截图02

于 2020-02-12T10:13:25.817 回答
0

我有完全相同的问题,并通过“简单实现”和“测试”方法永远解决了这个问题。想法是当编辑文本获得焦点时,滚动视图自动滚动到底部。让我告诉你如何......

首先你应该使用嵌套滚动视图作为主布局的父级

第二个添加一个库以找出键盘何时打开

implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:2.0.1'

第三个将此类添加到您的项目中

public class KeyboardUtil {
private View decorView;
private View contentView;
//a small helper to allow showing the editText focus
ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = 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);
            }
        }
    }
};

public KeyboardUtil(Activity act, View contentView) {
    this.decorView = act.getWindow().getDecorView();
    this.contentView = contentView;

    //only required on newer android versions. it was working on API level 19
    if (Build.VERSION.SDK_INT >= 19) {
        decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
    }
}

/**
 * Helper to hide the keyboard
 *
 * @param act
 */
public static void hideKeyboard(Activity act) {
    if (act != null && act.getCurrentFocus() != null) {
        InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
    }
}

public void enable() {
    if (Build.VERSION.SDK_INT >= 19) {
        decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
    }
}

public void disable() {
    if (Build.VERSION.SDK_INT >= 19) {
        decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
    }
}

public static void adjustResize(Activity activity, final NestedScrollView scrollView) {
    KeyboardVisibilityEvent.setEventListener(
            activity,
            new KeyboardVisibilityEventListener() {
                @Override
                public void onVisibilityChanged(boolean isOpen) {
                    // some code depending on keyboard visiblity status
                    if (isOpen) {

                        //Scroll view scrolls bottom without changing focus
                        View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);
                        int bottom = lastChild.getBottom() + scrollView.getPaddingBottom();
                        int sy = scrollView.getScrollY();
                        int sh = scrollView.getHeight();
                        int delta = bottom - (sy + sh);

                        scrollView.smoothScrollBy(0, delta);


                    } else {
                        //Toast.makeText(context, "keyboard is close", Toast.LENGTH_SHORT).show();

                    }
                }
            });} }

然后在你的活动中使用它

new KeyboardUtil(activity,nestedScrollView);
KeyboardUtil.adjustResize(activity,nestedScrollView);

如果您在片段中,您可以将以下代码作为活动传递:

(AppCompatActivity)context
于 2020-02-13T16:02:30.910 回答