显示键盘时,viewpager 片段内的滚动视图不会滚动
Scrollview inside a viewpager fragment doesnt scroll when keyboard is shown
我有一个activity,其布局内容如下:
<?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 区域重叠,而不是 scrollview 导致内容滚动。
我希望该片段能够处理显示的键盘,并希望滚动视图适合屏幕上的键盘。
或者我错了 activity 负责键盘? activitylayout中的root view是linearlayout,是不是限制了展开?
我尝试用滚动视图包裹 activity 布局的全部内容,但这次如果我不给它固定大小,viewpager 不会出现在屏幕上。 即使我这样做了,我最终还是在片段中有一个滚动视图,该片段位于主布局的滚动视图下方,并且键盘仍然悬停在编辑文本上。
我在这里有点迷路,我的 objective 是当编辑文本获得焦点时能够滚动片段内容,但键盘当前与编辑文本重叠。
我可能会弄错,但这可能是因为已知 Android 错误,您只需将下一个 class 添加到您的项目中:
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);
}
}
然后只需在包含 ViewPager
和 SlidingTabLayout
的 Activity 中调用 assistActivity()
方法即可使用它:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
AndroidBug5497Workaround.assistActivity(this);
...
}
更多背景调查 this 话题。
我对 ScrollView 中的 ListView 有类似的问题。您需要在 OnCrateView
.
ScrollView
类似的 OnTouchListener
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 可能对您有所帮助。
我认为您需要使用 adjustPan 或 adjustResize 来在显示键盘时自动调整 space。 根据文档:
"adjustResize" activity 的主 window 总是调整大小以便为屏幕上的软键盘腾出空间。
"adjustPan" activity 的主 window 未调整大小以为软键盘腾出空间。相反,window 的内容会自动平移,以便当前焦点永远不会被键盘遮挡,用户始终可以看到他们正在输入的内容。这通常不如调整大小可取,因为用户可能需要关闭软键盘才能找到 window.
的遮挡部分并与之交互您可以在 activity 标签下的清单中声明其中之一,如下所示: android:windowSoftInputMode="stateUnchanged|adjustResize
我希望这能满足您的要求。
您必须创建 ViewPager 的子 class,然后覆盖 onTouchEvent,如 this
所示