当键盘弹出时,ViewPager片段中的ScrollView无法滚动

7
我有一个布局内容如下的活动:

我有一个活动,其布局内容如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="?attr/colorPrimary"
     android:minHeight="?attr/actionBarSize"
     style="@style/ToolBarStyle.Event" />

    <com.mypackage.corecode.ui.view.SlidingTabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary_color" />

    <android.support.v4.view.ViewPager
        android:id="@+id/vendor_main_tabview_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

在ViewPager中,我有一个Fragment,该Fragment具有以下布局:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

                    <LinearLayout
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:weightSum="3"
                        android:orientation="horizontal">

                        <EditText
                            android:theme="@style/ScrollableContentThemeNoActionBar"
                            android:id="@+id/edit_text_vendor_sms_phone_number"
                            android:layout_width="0dp"
                            android:layout_weight="2"
                            android:layout_height="wrap_content"
                            android:inputType="number" />

                        <Button
                            android:id="@+id/button_send_sms"
                            android:layout_width="0dp"
                            android:layout_weight="1"
                            android:layout_height="wrap_content"
                            />
                    </LinearLayout>
         </LinearLayout>
 </ScrollView>

当碎片内的内容不适合屏幕时,滚动视图允许用户查看屏幕下方的内容。(正常工作)

问题是当edittext获得焦点时,键盘会覆盖edittext区域,而不是滚动视图导致内容滚动。

我希望该片段处理键盘显示并使滚动视图适应屏幕上的键盘。

或者我错了,键盘是由活动负责的吗?由于活动布局中的根视图是线性布局,它限制了扩展吗?

我尝试将活动布局的整个内容都用滚动视图包装起来,但这一次,如果我没有给它一个固定的大小,viewpager就不会出现在屏幕上。 即使我这样做了,我最终还是在主布局的滚动视图下有一个碎片内的滚动视图,而键盘仍然悬浮在edittext上面。

我有点迷茫了,我的目标是当edittext获得焦点时能够滚动片段内容,但目前键盘却遮挡了edittext。


你尝试过使用 android:windowSoftInputMode="adjustResize|adjustPan" 吗? - muratgu
是的,我已经尝试将它们添加到活动清单中了,如果这就是你的意思,但是没有成功。 - Mehmet Katircioglu
你能提供你的活动代码以测试你的问题吗? - tsiro
从adjustResize | adjustPan中删除adjustResize。然后尝试仅使用adjustPan。 - Anish Mittal
3个回答

7

我可能犯了错误,但这很可能是由于已知的Android bug引起的,你需要将下一个类添加到你的项目中:

public class AndroidBug5497Workaround {

    // 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 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);
    }

}

然后,在持有ViewPagerSlidingTabLayout的Activity中,只需调用assistActivity()方法即可使用:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(...);
    AndroidBug5497Workaround.assistActivity(this);
    ...
}

For more background check this thread.


不错的解决方案。但是我在适应我的情况时遇到了问题。我使用了一个视图分页器,在视图分页器的第一个片段中,我有另一个片段,它是父母子片段,并带有其中的ScrollView。问题是当我使用这个解决方案时,当我点击第一个EditText时它可以正常工作。但是当我点击下面的EditText时,它会在ScrollView下面创建额外的白色空间。当我选择滚动视图底部末尾的EditText时,这个白色空间会增加。你有遇到过这个问题吗?如果你能分享一下你的经验,我将不胜感激。 - Poorya
我也遇到了同样的问题@Poorya。你有什么解决办法吗? - BHARADWAJ Marripally

0

我认为你需要使用adjustPan或adjustResize来自动调整空间,当键盘显示时。

根据文档:

"adjustResize" 活动的主窗口总是被调整大小以为软键盘腾出空间。

"adjustPan" 活动的主窗口不会被调整大小以为软键盘腾出空间。相反,窗口的内容会自动平移,以便当前焦点永远不会被键盘遮挡,用户始终可以看到他们正在输入什么。这通常不如调整大小好,因为用户可能需要关闭软键盘才能访问和与窗口的遮挡部分交互。

您可以在活动标签下声明其中一个,如下所示:

android:windowSoftInputMode="stateUnchanged|adjustResize"

我希望这将满足您的要求。


0

你需要创建ViewPager的子类,然后重写onTouchEvent方法,如this所示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接