【问题标题】:Scrollview inside a viewpager fragment doesnt scroll when keyboard is shown显示键盘时,viewpager片段内的滚动视图不滚动
【发布时间】:2016-02-01 23:14:42
【问题描述】:

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

<?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 内部,我有一个片段,其布局如下:

<?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区域重叠,而不是滚动视图导致内容滚动。

我希望片段能够处理显示的键盘和滚动视图以适应屏幕上的键盘。

还是我错了,活动对键盘负责?由于activity layout中的root view是linearlayout,是不是限制了展开?

我尝试用滚动视图包装活动布局的全部内容,但是如果我不给它一个固定大小,这次 viewpager 不会出现在屏幕上。 即使我这样做了,我最终还是在主布局的滚动视图下的片段内有一个滚动视图,并且键盘仍然悬停在编辑文本上。

我在这里有点迷路,我的目标是能够在edittext获得焦点时滚动片段内容,而是键盘当前与edittext重叠。

【问题讨论】:

  • 你试过android:windowSoftInputMode="adjustResize|adjustPan"吗?
  • 是的,我已经尝试在活动清单中添加这些,如果这就是你的意思,但没有运气
  • 你能提供你的活动代码来测试你的问题吗?
  • 从adjustResize 中移除adjustResize |调整盘。然后尝试。仅使用adjustPan。

标签: android android-edittext scrollview window-soft-input-mode


【解决方案1】:

我可能弄错了,但可能是由于已知的 Android 错误,您只需将下一个类添加到您的项目中:

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

更多背景调查this线程。

【讨论】:

  • 很好的解决方法。但是我无法适应我的情况。我使用了一个视图寻呼机,在视图寻呼机的第一个片段中,我有另一个片段,它是一个带有滚动视图的子片段。问题是当我使用解决方法时,当我单击第一个 EditText 时效果很好。但是当我点击较低的时,它会在滚动视图下方创建一个额外的空白区域。当我在滚动视图底部选择一个 EditText 时,这个空白会增加。你遇到过这个问题吗?如果您能分享您的经验,我将不胜感激。
  • 我也面临同样的问题@Poorya。你有解决办法吗?
【解决方案2】:

我在 ScrollView 中的 ListView 也遇到了类似的问题。您需要在 OnCrateView 中添加类似的 OnTouchListenerScrollView

myList.setOnTouchListener(new ListView.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            // Disallow ScrollView to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(true);
            break;

            case MotionEvent.ACTION_UP:
            // Allow ScrollView to intercept touch events.
            v.getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }

        // Handle ListView touch events.
        v.onTouchEvent(event);
        return true;
    }
});

这是另一个SO Answer,可能会对您有所帮助。

【讨论】:

    【解决方案3】:

    我认为您需要在显示键盘时使用 adjustPan 或 adjustResize 来自动调整空间。 根据文档:

    "adjustResize" Activity 的主窗口总是调整大小,以便为屏幕上的软键盘腾出空间。

    "adjustPan" Activity 的主窗口没有调整大小来为软键盘腾出空间。相反,窗口的内容会自动平移,因此当前焦点永远不会被键盘遮挡,用户始终可以看到他们正在输入的内容。这通常不如调整大小可取,因为用户可能需要关闭软键盘才能到达窗口的模糊部分并与之交互。

    您可以在清单中的活动标签下声明其中之一,如下所示: android:windowSoftInputMode="stateUnchanged|adjustResize

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

    【讨论】:

      【解决方案4】:

      您必须创建 ViewPager 的子类,然后覆盖 onTouchEvent,如 this 所示

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-25
        • 2015-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多