活动与碎片一起使用时,键盘打开时不会重新调整大小

30

在我的主活动中有一个RelativeLayout,它有两个子项:

  • 作为背景的ImageView
  • 包含2个片段容器的LinearLayout

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="bottom"
    tools:context="${packageName}.${activityClass}">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:baselineAlignBottom="false"
        android:scaleType="fitStart"
        android:src="@drawable/bg_image" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingTop="?android:attr/actionBarSize"
        android:layout_alignParentBottom="true">

        <LinearLayout
            android:id="@+id/ContainerA"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="vertical" />
        
        <LinearLayout
            android:id="@+id/ContainerB"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/background_gray"
            android:orientation="vertical" />

    </LinearLayout>
</RelativeLayout>

容器 A 显示的是一个不会改变的片段。 然而,容器 B 包含一个随用户点击而改变的片段。

容器 B 有 2 种变化方式:

  • 它可以扩展(从大约 70% 的高度到完全高度)。
  • 它会更换片段。

容器 B 可以包含的片段之一是一个表单,其中包含 EditText 和其他视图。

我的问题是当键盘打开时无法调整活动的大小。 我在清单文件中设置了 adjustResize,并且我的主题不是全屏主题(这显然是此问题的原因)。我还尝试编辑视图,添加 ScrollViews,但绝对没有任何作用。

我为此活动使用的主题是来自 AppCompat 库的深色操作栏的浅色主题。我只编辑了主题以允许覆盖操作栏。这不是问题,因为我已经尝试删除这些编辑,但仍然无济于事。

这里是表单布局的链接

TL;DR 对于我来说,adjustResize/ adjustPan 不起作用。我搜索了,尝试了各种解决方案,但什么都没用。我的问题是:在我的情况下,这是什么原因?

更新: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>

    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="19" />

    <application ... android:theme="@style/AppTheme">
        <activity android:name=".SplashScreenActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Black.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity"
            android:configChanges="keyboardHidden|screenSize" android:label="@string/app_name"
            android:screenOrientation="portrait" android:theme="@style/OverlayActionBarTheme"
            android:windowSoftInputMode="adjustResize"  />
        <activity android:name=".SettingsActivity"
            android:label="@string/title_activity_settings"
            android:parentActivityName=".MainActivity"
            android:windowSoftInputMode="adjustResize">
            <meta-data android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>
    </application>

</manifest>

更新2:
我创建了一个全新的应用,将我的表单布局添加为主布局,并测试了问题是否出现在布局本身。结果是,在这个新创建的应用中,它似乎不会调整大小。

如上所述,可以在此处找到布局的链接。

更新3: 我设法在新应用程序中通过使用ScrollView来包围整个布局使其正常工作。由于某种原因,我无法在原始应用程序中复制相同的效果......仍在努力找出原因。


你可以发布一张图片来展示它是什么样子吗? - Rod_Algonquin
@xTCx,你尝试过在主活动B片段的XML中都使用滚动视图吗? - Nadeem Iqbal
请不要使用多层LinearLayout(即使用多个LinearLayout嵌套),而是可以使用RelativeLayout来简化布局。 - Vaishali Sutariya
7个回答

31

当软键盘出现在屏幕上时,可用于应用程序UI的空间会减少。系统会决定如何在应用程序的UI和软键盘之间组织可用空间。

  • 如果窗口内容包含 ListViewScrollView,则提供所有内容可见的前提下调整应用程序窗口大小。
  • 如果无法调整大小,则采用 pan and scan 方法,简单地滚动应用程序窗口以使当前聚焦视图可见。

由于你的布局不包含任何 ListViewScrollView,因此排除了调整大小的可能性。

窗口的根视图是一个 FrameLayout,最初向其中添加了 LinearLayout。由于 LinearLayout 不支持滚动,因此 pan and scan 方法也被排除。因此,将布局包装在 ScrollView 中可以解决滚动问题。

有关更多详细信息,可以参考Android 开发者博客

更新1:

正如这个答案所示,OP 已经解决了这个问题。问题是由于一片碎片在动画后覆盖另一片碎片,并且这些Fragment的父级是一个LinearLayout。为了覆盖目的,您只能使用RelativeLayoutFrameLayout


嗨,感谢您的评论。这实际上非常接近真正的“解决方案”,请阅读我的下面的答案并编辑您的答案,以便我可以将其标记为已接受! :) - Asaf
这是如此详细的解释,以至于我决定尝试将我的片段放在嵌套滚动视图中,并解决了我的问题。谢谢! - Beto

15

您也可以在Fragment中使用此代码

此代码可帮助调整视图大小。

public static class MyDialog extends DialogFragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // Dialog layout inflater code
    // getDialog() need to be called only after onCreateDialog(), which is invoked between onCreate() and onCreateView(). 
      getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |     WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
   // return view code
  }
}

这是唯一在我的“Fragment”中有效的,谢谢! - Sakiboy
在ViewPager内部的Fragment中对我有用。 - Rohaitas Tanoli

13

将以下语句中的模式更改为“resize”,并将其添加到您在“AndroidManifest.xml”中的活动中。

 <activity android:name=".ActivityName"
        android:windowSoftInputMode="adjustResize">

请尝试使用RelativeLayout来设置布局,而不是使用LinearLayout的多层嵌套方式,这样可以更轻松地实现您想要的布局。希望这能够解决你的问题。

希望对你有所帮助。


8

1
最后什么都没帮上忙,但这个确实帮了很多。 - Drim
2
这应该是被接受的答案!这是唯一有效的方法! - Vlad Alexeev
可以滚动内容,但它不会自动跳转。 - Choletski

6
结果发现我的问题是由一个完全意想不到的来源造成的。我的两个片段容器的父容器使用了LinearLayout,然后在我的扩展动画中,我将底部容器提升以重叠另一个容器。
我不知道为什么,但由于LinearLayout不能容纳重叠的子项,所以换成RelativeLayout或FrameLayout立即解决了这个问题。
由于这个原因可能不明显,所以我要为缺乏信息而道歉,并将最详细的答案列为最佳答案。

6

在您希望获取结果的活动中,在清单文件中使用此行

希望这能帮到您。
   android:windowSoftInputMode="adjustPan|stateAlwaysHidden" 

喜欢

  <activity
            android:name="com.android.youractivity"
            android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />

谢谢。不幸的是,我之前已经尝试过了,但没有成功。 - Asaf

1
在DialogFragment Oncreateview中R.layout.layout_ui下方添加以下代码行。
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN |     WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

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