android:windowSoftInputMode="adjustResize" 没有任何区别?

Posted

技术标签:

【中文标题】android:windowSoftInputMode="adjustResize" 没有任何区别?【英文标题】:android:windowSoftInputMode="adjustResize" doesn't make any difference? 【发布时间】:2012-01-13 22:45:28 【问题描述】:

我有一个使用这种布局的人造对话框:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout    xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_
                android:layout_
                android:id="@+id/containerPageConatiner">

    <FrameLayout    android:id="@+id/dialogHolder"
                    android:layout_
                    android:layout_
                    android:padding="15dp"
                    android:layout_gravity="center"
                    android:background="@drawable/panel_picture_frame_bg_focus_blue"/>    
</FrameLayout> 

我根据正在打开的对话框在&lt;FrameLayout&gt; 中放置一个片段 - 控制对话框的活动如下所示:

<activity
    android:label="@string/app_name"
    android:name=".activity.DialogActivity"
    android:theme="@style/CustomTheme.Screen.Transparent" 
    android:windowSoftInputMode="adjustResize">

不幸的是,当您单击对话框内的编辑文本时,不会调整大小。 windowSoftInputMode 实际上没有区别,因为功能与平移模式相同。

Documentation 说“这当然只适用于具有可调整大小的区域的应用程序,可以缩小以腾出足够的空间”,但没有告诉你“可调整大小的区域”是什么意思,让我认为在以某种方式我没有有一个可调整大小的区域?

如果有人知道怎么回事,可以帮帮我吗?

编辑

像这样围绕对话框不会改变任何东西:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/containerPageConatiner"
    android:layout_
    android:layout_
    android:orientation="vertical" >

    <View
        android:layout_
        android:layout_
        android:layout_weight="1" />

    <FrameLayout    
        android:id="@+id/dialogHolder"
        android:layout_
    android:layout_
        android:padding="15dp"
        android:layout_gravity="center"
        android:background="@drawable/panel_picture_frame_bg_focus_blue"/>

    <View
        android:layout_
        android:layout_
        android:layout_weight="1" />
</LinearLayout>

EDIT2

Scrollview 作为父级也无济于事:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/containerPageConatiner"
    android:layout_
    android:layout_ >

    <FrameLayout
            android:id="@+id/dialogHolder"
            android:layout_
            android:layout_
            android:layout_gravity="center"
            android:padding="15dp" />

</ScrollView>

【问题讨论】:

使用一个 EditText 进行检查。在edittect里面点击显示软键盘,现在可以看到这个android:windowSoftInputMode=“adjustResize”的使用了。你是否使用了adjustNothing,即使键盘显示你的布局也不应该有任何变化。 对不起,我听不懂。 【参考方案1】:

我创建了一个新项目,以尝试获得用于调整窗口大小的基本功能,并慢慢将其移向我项目的目标部分。这样做我将问题归结为:

在我的主题层次结构中,我有这个属性:

<item name="android:windowFullscreen">true</item> 

埋藏在Theme.Black.NoTitleBar.FullScreen 级别 - 我的自定义主题的祖先。

documentation 表明这是一个“指示此窗口是否应填满整个屏幕的标志”。如果您有一个占据整个屏幕的应用程序,这听起来是一件好事......但它仍然占据整个屏幕而没有标志。

事实上,一旦你把它拿出来,应用程序绝对没有任何变化......除了adjustResize现在可以完美运行。

【讨论】:

感谢这篇文章!但我想要全屏和调整大小。 :( 重新阅读答案。无论windowFullscreen 设置为 true、false 还是不存在,您的 Activity 仍将是全屏的。 好的。我认为我的问题是,我没有自己的主题。它就像您使用自己的主题编写一样。 :) 当我从我的自定义主题中删除 android:windowFullscreen 时,不幸的是它不再是全屏(操作系统 4.1)。你可以发布你的主题的完整代码吗?也许我的实现中缺少一些东西。 我将添加我的观察。 Graeme 对 android:windowFullscreen 属性是正确的。它隐藏了状态栏(顶部有时钟和通知等)。这样做的结果是在 adjustResize 设置的属性 android:windowSoftInputMode 不能按预期运行。当显示软键盘时,活动占用了所有可用空间,并且不知道软键盘占用了一些空间。因此无法滚动到活动的底部。【参考方案2】:

不久前,我在创建的库中也遇到了同样的问题。 (MaterialDrawer)

据我所知,所有提供的答案都没有解决主要问题,他们只是指出删除全屏标志 (android:windowFullscreen),这对很多人来说都没有解决方案。

上述“问题”仅出现在从 API 级别 19 (KITKAT) 开始的 Android 版本中,因为它们改变了行为。正确地说,这不是问题,它按预期工作。请参阅 Android 员工 (Android-Issue) 的评论。


所以我开始挖掘 Android 源代码,并通过使用 ViewTreeObserver.OnGlobalLayoutListener 并在键盘显示/隐藏时做出反应来得出以下解决方案。如果显示键盘,我将填充添加到容器视图的底部,然后将模拟与 adjustResize 相同的效果。


解决方案

为了简化使用,我将整个内容封装在一个简单的 KeyboardUtil 辅助类中。

/**
 * Created by mikepenz on 14.03.15.
 * This class implements a hack to change the layout padding on bottom if the keyboard is shown
 * to allow long lists with editTextViews
 * Basic idea for this solution found here: http://***.com/a/9108219/325479
 */
public class KeyboardUtil 
    private View decorView;
    private View contentView;

    public KeyboardUtil(Activity act, View contentView) 
        this.decorView = act.getWindow().getDecorView();
        this.contentView = contentView;

        //only required on newer android versions. it was working on API level 19 (Build.VERSION_CODES.KITKAT)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        
    

    public void enable() 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        
    

    public void disable() 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
        
    


    //a small helper to allow showing the editText focus
    ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() 
        @Override
        public void onGlobalLayout() 
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            decorView.getWindowVisibleDisplayFrame(r);

            //get screen height and calculate the difference with the useable area from the r
            int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
            int diff = height - r.bottom;

            //if it could be a keyboard add the padding to the view
            if (diff != 0) 
                // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                //check if the padding is 0 (if yes set the padding for the keyboard)
                if (contentView.getPaddingBottom() != diff) 
                    //set the padding of the contentView for the keyboard
                    contentView.setPadding(0, 0, 0, diff);
                
             else 
                //check if the padding is != 0 (if yes reset the padding)
                if (contentView.getPaddingBottom() != 0) 
                    //reset the padding of the contentView
                    contentView.setPadding(0, 0, 0, 0);
                
            
        
    ;


    /**
     * Helper to hide the keyboard
     *
     * @param act
     */
    public static void hideKeyboard(Activity act) 
        if (act != null && act.getCurrentFocus() != null) 
            InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
        
    


然后您可以通过执行以下操作在您的活动或片段中使用它:

//initialize the KeyboardUtil (you can do this global)
KeyboardUtil keyboardUtil = new KeyboardUtil(activity, getContent().getChildAt(0));

//enable it
keyboardUtil.enable();

//disable it
keyboardUtil.disable();

上面提到的库MaterialDrawer中使用了整个util类,可以在这里找到KeyboardUtil。这将始终包含最新版本。 (如果有改进)

【讨论】:

评论的 73 只是表明这是我设备上的 dp 的信息。你不必设置这个或任何东西。我只保留初始高度以防止检测出现问题 在使用不同主题的应用程序中,您可能需要在应用修复之前查询当前窗口是否设置了WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUSFLAG_TRANSLUCENT_NAVIGATION。修复了我遇到的一个问题。 如果屏幕上有一个数字字段和一个字母字段,就会发生有趣的效果。首先单击数字字段会正确调整屏幕,然后更改为 alpha 字段会使键盘变大(自动更正解决方案位于键盘上方),并且屏幕不会重新调整。 你有我迄今为止发现的唯一可行的解​​决方案 - 干得好!如果我设法解决这个极端情况,我一定会通知你。 它对我有用!但是,我不知道为什么“getContent”对我不起作用,但我将其替换为: ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0)【参考方案3】:

似乎问题出在 FrameLayout 上,因为它的行为方式是,每个子项都占用了该帧的可见空间,因此无需调整大小以适应子项。 尝试使用相对布局。它应该可以工作。

【讨论】:

使用 RelativeLayout 代替 FrameLayout 的问题完全相同。正如您从编辑中看到的那样,LinearLayout 也无济于事。 尝试将android:fillViewport="true"添加到ScrollView +1 frameLayout 对我来说与 android:windowSoftInputMode="adjustResize" 不兼容,将视图移到我的 frameLayout 之外修复了它。但是,这仅不适用于 4.0.4【参考方案4】:

没有使用ScrollView 作为我的父级,我只是将android:fitsSystemWindows="true" 添加到我的父级视图(这是一个RelativeLayout)和adjustResize 到活动的清单中,并且它起作用了。

【讨论】:

【参考方案5】:

尝试将您的LinearLayout 放在ScrollView 上,这对我有用..

【讨论】:

即使使用 ScrollView 作为父级,单击对话框内的 EditText 也不会调整屏幕任何部分的大小。【参考方案6】:

我不得不设置

<item name="android:windowFullscreen">false</item> 

尽管如此,我从未将其设置为 true,并且应用实际上不是全屏的。

【讨论】:

【参考方案7】:

我不知道为什么,但是如果您的主题中有&lt;item name="android:windowTranslucentNavigation"&gt;true&lt;/item&gt;,请将其更改为false。它将开始工作。真奇怪。

【讨论】:

@Bro,你让我开心。从过去的两天开始,我只是在努力解决这个问题,但没有成功。效果很好,谢谢!【参考方案8】:

正如原始海报在将全屏标志分配给活动时发现的那样,android:windowFullscreen 属性将不起作用,因此当软键盘可见且无法滚动时,您的窗口将不会调整大小。

只要移除 Fullscreen 标志而不使用 Fullscreen 主题,就可以在软键盘可见时进行滚动。

【讨论】:

【参考方案9】:

确保在您的样式中将windowTranslucentStatus 设置为false

【讨论】:

以上是关于android:windowSoftInputMode="adjustResize" 没有任何区别?的主要内容,如果未能解决你的问题,请参考以下文章