Android AdjustResize 未正确调整大小

Android AdjustResize not resizing correctly

我正在使用这个库:https://github.com/yshrsmz/KeyboardVisibilityEvent 来检测键盘何时打开或关闭,这依赖于 android:windowSoftInputMode="adjustResize" 被输入到 Android 清单。

这个库可以完美地检测软键盘的打开和关闭事件,但由于 adjustResize 参数,我的内容被推出视图。

因此,通过调整第二个 EditText 的行,效果很好,然后我在键盘上方打字,但是当我关闭键盘时,滚动到该 EditText 的底部并单击底部,EditText 光标是放置在我单击的位置,但随后它将第一个 EditText 和 Support ActionBar 推出视图并在底部留下一个大间隙(如下图(图 2)所示,选择了 'F' ,即 EditText 的底部)。

我也曾尝试使用 'adjustNothing' 并执行以下操作,但这似乎也不起作用,因为在更改行数和行数之前,EditText 高度不会更改只有当它知道键盘是打开还是关闭时才会改变。

private void setupListeners() {

    final View activityRootView = getWindow().getDecorView().findViewById(android.R.id.content);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {

            View mainView = (LinearLayout) findViewById(R.id.add_record);
            int heightDiff = mainView.getHeight() - noteEditText.getHeight();
            Log.d("KB", "HeightDiff: " + heightDiff);
            if (heightDiff > 1000 || keyboardShown) { // 99% of the time the height diff will be due to a keyboard.
                Log.d("KB", "Keyboard is open");

                if (isKeyboardVisible) {
                    noteEditText.setLines(12);
                    noteEditText.setCursorVisible(true);
                    noteEditText.requestLayout();
                    isKeyboardVisible = false;
                }
            } else {
                Log.d("KB", "Keyboard is closed");

                if (!isKeyboardVisible) {
                    noteEditText.setLines(50);
                    noteEditText.setCursorVisible(false);
                    noteEditText.requestLayout();
                    isKeyboardVisible = true;
                }
            }
        }
    });

    noteEditText.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            numTimesClicked++;
            Log.d("KB", "onClick: " + numTimesClicked);

            if (clicked) {
                // Run function
                Log.d("KB", "clicked");
                InputMethodManager imm = (InputMethodManager) AddActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);

                if (imm.isAcceptingText()) {
                    Log.d("KB", "Software Keyboard was shown");
                    isKeyboardVisible = true;
                    keyboardShown = true;
                } else {
                    Log.d("KB", "Software Keyboard was not shown");
                    isKeyboardVisible = false;
                    keyboardShown = false;
                }
            } else {
                Log.d("KB", "scroll");
                clicked = true;
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        clicked = false;
                    }
                }, 3 * 1000);
            }
        }
    });

    noteEditText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                Log.d("KB", "closeKeyboard");
                noteEditText.setLines(50);
                noteEditText.setCursorVisible(false);
                noteEditText.requestLayout();
                isKeyboardVisible = false;
            }
            return false;
        }
    });

因此,我将如何实现调整 EditText 行(当键盘打开和关闭时)的预期效果而不将其他内容推出视图?那么支持ActionBar和第一个EditText始终保持在同一个位置,只有第二个EditText在出现软键盘时调整?

我不确定,但我相信如果您将布局内容保持在 ScrollView 下,并且每次用户输入新行或新词时,您都会设置 scrollView.scrollTo(0,0)。 另外,您可以使用 ViewTreeObserver,而不是这个库,请参考 here

您也可以使用 onFocusChangeListener() 进行管理,这是更好的做法。

我现在已经设法解决了这个问题(不是最好的解决方案),但它确实有效。顶部的 EditText 和 Support ActionBar 现在永远不会被推出视图,第二个 EditText 会自行调整大小,无论选择哪一行。

清单:

<activity android:theme="@style/AppTheme"
        android:name=".activities.AddActivity"
        android:label="@string/add_record"
        android:windowSoftInputMode="stateVisible|adjustResize"
        android:parentActivityName=".MainActivity"
        android:excludeFromRecents="true"/>
    <activity android:theme="@style/AppTheme"
        android:name=".activities.ModifyActivity"
        android:label="@string/modify_record"
        android:windowSoftInputMode="stateAlwaysHidden|adjustResize"
        android:parentActivityName=".MainActivity"
        android:excludeFromRecents="true"/>

Java:

private void setupListeners() {

    final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.add_record);
    if (linearLayout != null) {
        linearLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Clicking ll");
                noteEditText.requestFocus();

                InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                inputMethodManager.toggleSoftInputFromWindow(linearLayout.getApplicationWindowToken(),
                        InputMethodManager.SHOW_FORCED, 0);
            }
        });
    }

    KeyboardVisibilityEvent.setEventListener(
            AddActivity.this,
            new KeyboardVisibilityEventListener() {
                @Override
                public void onVisibilityChanged(boolean isOpen) {
                    // some code depending on keyboard visiblity status
                    Log.d(TAG, "Keyboard visibility changed");

                    int currentLine = getCurrentCursorLine(noteEditText);

                    lineCount = noteEditText.getLineCount();

                    if (isOpen && keyboardActuallyOpen) {
                        Log.d(TAG, "Keyboard is open");
                        //keyboardActuallyClosed = false;

                            /*
                            scrollView.fullScroll(View.FOCUS_UP);
                            noteEditText.requestFocus();
                            */

                        if (currentLine < 25) {

                            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);

                            scrollView.scrollTo(0, 0);

                            noteEditText.setMinLines(12);
                            noteEditText.setLines(12);
                            noteEditText.setMaxLines(12);
                            scrollView.scrollTo(0, 0);

                            noteEditText.setVerticalScrollBarEnabled(true);
                            scrollView.setVerticalScrollBarEnabled(false);
                            noteEditText.setCursorVisible(true);

                            scrollView.requestLayout();
                            noteEditText.requestLayout();
                        } else {

                            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

                            scrollView.scrollTo(0, 0);
                            noteEditText.setMinLines(12);
                            noteEditText.setLines(12);
                            noteEditText.setMaxLines(12);
                            scrollView.scrollTo(0, 0);

                            noteEditText.setVerticalScrollBarEnabled(true);
                            scrollView.setVerticalScrollBarEnabled(false);
                            noteEditText.setCursorVisible(true);
                        }
                    } else {

                        if (!keyboardActuallyOpen) {


                            lineCount = noteEditText.getLineCount();

                            Log.d(TAG, "Keyboard is closed: " + lineCount);
                            noteEditText.setVerticalScrollBarEnabled(false);
                            scrollView.setVerticalScrollBarEnabled(true);
                            noteEditText.setCursorVisible(false);

                            noteEditText.setMinLines(lineCount);
                            noteEditText.setLines(lineCount);
                            noteEditText.setMaxLines(lineCount);
                            scrollView.scrollTo(0, 0);

                            keyboardActuallyOpen = false;

                            //scrollView.requestFocus();
                            //setAdjustResize(1);

                            LinearLayout mainLayout = (LinearLayout) findViewById(R.id.add_record);
                            if (mainLayout != null) {
                                mainLayout.requestFocus();
                            }
                        }

                    }
                }
            });

    noteEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            Log.d(TAG, "onFocusChange");

            if (firstStart) {
                scrollView.scrollTo(0, 0);
                noteEditText.setLines(12);
                noteEditText.setCursorVisible(true);
                firstStart = false;
            }

            if (hasFocus) {
                Log.d(TAG, "Has Focus");
                keyboardActuallyOpen = true;
            } else {
                Log.d(TAG, "Lost focus");
                keyboardActuallyOpen = false;
                setAdjustResize(2);
            }
        }
    });
    noteEditText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                Log.d(TAG, "closeKeyboard");

                keyboardActuallyOpen = false;

                noteEditText.setMinLines(lineCount);
                noteEditText.setLines(lineCount);
                noteEditText.setMaxLines(lineCount);

                noteEditText.setVerticalScrollBarEnabled(false);
                noteEditText.setCursorVisible(false);
                noteEditText.requestLayout();

                scrollView.scrollTo(0, 0);
                scrollView.setVerticalScrollBarEnabled(true);
                scrollView.requestLayout();

                noteEditText.clearFocus();
            }
            return false;
        }
    });


}

Java(sub-classed 按下键盘关闭按钮的 EditText):

public class ExtendedEditText extends EditText {

public ExtendedEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

}

public ExtendedEditText(Context context, AttributeSet attrs) {
    super(context, attrs);

}

public ExtendedEditText(Context context) {
    super(context);

}

@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
        dispatchKeyEvent(event);
        return false;
    }
    return super.onKeyPreIme(keyCode, event);
}

}

XML

    <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/add_scrollView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:descendantFocusability="beforeDescendants"
    android:focusableInTouchMode="true"
    android:fillViewport="true">

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/add_record"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="20dp"
        android:focusable="true"
        android:focusableInTouchMode="true">

        <EditText
            android:id="@+id/title_edittext"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="@string/enter_title"
            android:inputType="textCapSentences"
            android:textColor="@color/fontPrimary"
            android:theme="@style/EditTextCustomCursor">
        </EditText>

        <com.securenotes.utils.ExtendedEditText
            android:id="@+id/note_edittext"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            android:ellipsize="end"
            android:gravity="top|left"
            android:hint="@string/enter_note"
            android:inputType="textCapSentences|textMultiLine"
            android:lines="50"
            android:maxLines="20"
            android:minLines="5"
            android:paddingLeft="5dp"
            android:scrollHorizontally="false"
            android:scrollbars="vertical"
            android:textColor="@color/fontPrimary"
            android:theme="@style/EditTextCustomCursor" />

    </LinearLayout>
</ScrollView>