如何做好全屏化的交互体验(解决EditText导致的界面上移、挡住等问题)
2017-04-14 16:27
381 查看
EditText导致的问题
在使用EditText并且将其放在屏幕底部的时候,往往会使用例如:
android:windowSoftInputMode="adjustResize|stateHidden"1
1
等这样的参数,但是它有着很大的缺点,会导致界面上移、
EditText被挡住的问题一些问题。
简单思考EditText键盘弹出后为什么导致界面上移呢?
不从代码层次上考虑,当键盘弹出后,键盘本身占据一定空间会致使EditText随之上移,
EditText上移也会导致同一布局层次的其他控件发生位移状况,这就是我们常常碰到的情况,也是非常头痛。
那么,如果将
EditText放在一个独立层次的控件中,并且让其上部(因为往往
EditText都会放在底部)有一个自动控制其大小宽高的控件,是不是就会解决这个问题呢?
答案是肯定的!
将EditText放入独立的层次布局中,并辅以可自动收缩的控件。
类似于这样:<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/send_edt" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:gravity="center_vertical|left" android:imeOptions="actionSend|flagNoExtractUi" android:lines="1" android:minHeight="38dp" android:padding="5dp" android:textColor="#222222" android:textColorHint="#b4b4b4" android:textSize="13sp" android:visibility="visible" /> <!--也可以是RecyclerView或ListView,但是不能是LinearLayout或RelativeLayout等布局--> <ScrollView android:layout_width="0dp" android:layout_height="match_parent" android:layout_above="@id/send_edt" /> </RelativeLayout>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
你可以直接将这段代码放入到你的Demo中,就会惊人的发现
EditText会如你所愿的弹出。
但是问题真正结束了么?当然没有。
在全屏化的体验中,我们的背景往往是一个
VideoView或
SurfaceView等类似的播放控件。
如果仅仅按照我们如上所示的做,你会发现
VideoView或
SurfaceView这样的控件,在播放时播放内容会被自动缩小,这也是我们不可接受的。
此时,我的布局如下:
<FrameLayout 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:background="#0099cc" tools:context="com.bzh.FullscreenActivity"> <!-- The primary full-screen view. This can be replaced with whatever view is needed to present your content, e.g. VideoView, SurfaceView, TextureView, etc. --> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#CCFF00FF" android:padding="30dp"> <VideoView android:layout_centerInParent="true" android:id="@+id/fullscreen_content" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#55ff00ff" /> </RelativeLayout> <!-- This FrameLayout insets its children based on system windows using android:fitsSystemWindows. --> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/send_edt" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:gravity="center_vertical|left" android:imeOptions="actionSend|flagNoExtractUi" android:lines="1" android:minHeight="38dp" android:padding="5dp" android:textColor="#222222" android:textColorHint="#b4b4b4" android:textSize="13sp" android:visibility="visible" /> <!--也可以是RecyclerView或ListView,但是不能是LinearLayout或RelativeLayout等布局--> <ScrollView android:layout_width="0dp" android:layout_height="match_parent" android:layout_above="@id/send_edt" /> </RelativeLayout> </FrameLayout> </FrameLayout>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
那么如何解决这个问题? 我在Google的全屏化Demo中找到了灵感。
借助View.setSystemUiVisibility()
方法来达到真正的全屏化目的
很多同学查阅Android如何全屏化的时候,往往都会得到如下的结果:getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);1
1
使用
Window的flag来达到目的,但是千万不要这么作,如果你的全屏化状态带有和用户交互的行为,你就应该选择另一种全屏化代码:
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);1
1
具体详细的例子可以看Google的官方例子:
AndroidStudio -> NewProject -> 项目名 -> 选择模板(FullScreen)1
1
当我们加上如上代码时键盘弹出就不会导致
VideoView控件播放内容被挤压了。
但是,问题还没有结束,你会发现
EditText的输入框不见了。
Why?这是因为
EditText并没有随着
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN生效后自动调整。
这个问题的解决办法Google的FullScreen例子也给出了解决办法,加入
android:fitsSystemWindows.:
<!-- This FrameLayout insets its children based on system windows using android:fitsSystemWindows. --> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true">1
2
3
4
5
6
1
2
3
4
5
6
至此,
EditText所引发的问题就得到解决了。
Demo地址 [https://github.com/biezhihua/FullScreenDemo]
View.setSystemUiVisibility介绍
public void setSystemUiVisibility(int visibility)1
1
达到交互式全屏化是调用了上述方法,并通过改变参数来达到隐藏和显示状态栏的目的,其方法简介如下:
改变状态栏或者屏幕其他系统UI的可见性。
允许你App的内容放置在系统操作栏(状态栏)之下,通过平滑的过度效果来隐藏和显示系统UI。
使用这个方法让用户集中更多的注意力在你应用的内容上。
典型的使用到这个方法的场景是:杂志阅读器/视频播放器
总结来说,如果你做的是视频播放器,使用这个方法来达到全屏化的目的,比单纯调用下面的方法来达到全屏化,得到的交互效果会更加流畅和丝滑。
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);1
1
Flags参数到底是什么意思?
接下来,我们就挨个看看这些常量都是什么意思。
View.SYSTEM_UI_FLAG_LOW_PROFILE View.SYSTEM_UI_FLAG_FULLSCREEN View.SYSTEM_UI_FLAG_LAYOUT_STABLE View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION View.SYSTEM_UI_FLAG_HIDE_NAVIGATION View.SYSTEM_UI_FLAG_LOW_PROFILE1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
请求系统UI进入一个“低调”的模式。在游戏,阅读器,视频播放器等需要“沉浸式”体验的应用中,系统UI常常会让用户分心。在这种模式下,状态栏和导航栏会变暗。
View.SYSTEM_UI_FLAG_FULLSCREEN1
1
请求进入全屏模式,但同时仍然允许用户与系统UI进行交互,这与WindowManager.LayoutParams.FLAG_FULLSCREEN具有相同的视觉效果,一些非关键画面UI(如状态栏)将被隐藏。
但是,WindowManager.LayoutParams.FLAG_FULLSCREEN更强调让用户一直处于一个连续的状态,比如玩游戏。而这个标记则更强调一种沉浸状态,用户可以迅速的退出这种状态。
举个例子,我们看小说的时候,很多时间会专心与小说本身,但是当用户想看一下时间时,点击屏幕,我们可以迅速友好显示系统UI和一些操作控制UI。
View.SYSTEM_UI_FLAG_LAYOUT_STABLE1
1
简单来说,就是防止隐藏和显示系统UI时,控件发生抖动。
如果加上这个设置,无论怎么显示和隐藏系统UI,我们都回到得到一个平滑的过渡效果。
假如你设置了WindowManager.FLAG_FULLSCREEN标记而不是View.SYSTEM_UI_FLAG_FULLSCREE,那么你将得到一直处于隐藏状态的状态栏。
注意,改变或清除WindowManager.FLAG_FULLSCREEN不会得到一个平滑的过渡效果。
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY1
1
效果是增强显示和隐藏系统UI时的交互体验。
如果不设置的话,那么任何与系统UI的交互,都会导致退出全屏状态。如果设置的话,那么系统UI会短暂的覆盖应用的内容,而且还有一定程度的透明度,并且短暂时间后自动隐藏,并不会退出全屏化。
看一下效果图会更明显一些。
这是全屏化状态
这是设置后的效果。
这是未设置的效果,与系统UI交互直接退出全屏状态。
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN1
1
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION1
1
如果窗口有被设置为SYSTEM_UI_FLAG_FULLSCREEN的需求,那么请设置这两个标记,这样可以避免切换系统UI显示与隐藏时,AppUI被覆盖。
如果不设置就会出现下面的情况。
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION1
1
隐藏导航栏
以上都是被全屏化的View所需要进行的处理。对于控制器来说,如果不在布局中设置
android:fitsSystemWindows=true属性,那么控制器的UI就会跑到状态栏的下面。
为了避免以上的情况,就不得不解释
setFitsSystemWindows(boolean)和
fitSystemWindows(rect)方法了。
setFitsSystemWindows()方法是设置此视图是否应该考虑系统UI,例如状态栏。并为其留出空间。如果参数为true,代表会为系统UI留出空间,那么
fitSystemWindows(rect)会被执行。
而
fitSystemWindows(rect)方法是,当Window内容的边距发生改变时(进入全屏化),允许调用该方法调正我们App的UI,以适应Window的变化。
正常情况下,系统UI会入侵到AppUI的一些空间(状态栏,输入法,导航栏等),也就是我们App的UI不会出现在系统UI之下。
不过万一你使用了SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION ,你的内容可能会被系统UI覆盖。此时,你能调用这个方法,来确保你的UI不会被系统的UI覆盖。
这个方法的简单实现是使用padding来做到的,并且这个方法默认是不执行的。
其实,在横屏全屏状态下,之所以EditText不会被输入法遮挡,都是由于执行了这个方法
Java和Android架构
Java和Android架构是一个数万人关注的探讨Java和Android开发的公众号,分享和原创最有价值的干货文章,让你成为这方面的大牛!
我们探讨android和Java开发最前沿的技术:android性能优化 ,插件化,跨平台,动态化,加固和反破解等,也讨论设计模式/软件架构等。由一群来自BAT的工程师组成的团队。
关注即送红包,回复:“百度”
、“阿里”、“腾讯” 有惊喜!!!关注后可用入微信群。群里都是来自百度阿里腾讯的大牛。
欢迎关注我们,一起讨论技术,扫描和长按下方的二维码可快速关注我们。或搜索微信公众号:JANiubility。
公众号:JANiubility
相关文章推荐
- 如何做好全屏化的交互体验(解决EditText导致的界面上移、挡住等问题)
- 如何做好全屏化的交互体验(解决EditText导致的界面上移、挡住等问题)
- 如何解决iOS界面操作导致导致NSTimer暂停计时的问题?
- 如何解决企事业信息系统越来越多导致的帐号密码安全及管理混乱问题
- ThinkPad增值软件Access Connections导致Windows欢迎界面改变问题与解决
- 如何解决XML文件中特殊字符“& <”导致解析错误的问题
- 如何解决 Android 软键盘弹出,会把原来的界面挤上去的问题?
- Android 解决SurfaceView切换导致界面闪烁,短暂黑屏问题。
- 如何解决BitBlt打印BMP,数据量太大导致速度效率慢的问题
- IE中ajax+jsp登录界面,由于缓存导致jsp过滤器与ajax请求被拦截的问题和解决
- 如何解决Android中输入法挡住输入框的问题
- 如何解决Android中输入法挡住输入框的问题
- Android 如何解决默认壁纸更改为ImageWallpaper之外的壁纸,在特定的操作下,导致死机的问题。
- 如何解决由于服务过多或异常导致ArcGIS Server 无法正常运行的问题
- 教你如何将txt复制到excel的各个单元格;并解决科学计数法显示问题及导致的个位数变0问题
- IE中ajax+jsp登录界面,由于缓存导致jsp过滤器与ajax请求被拦截的问题和解决
- 如何解决更改解决服务器IP,导致应用程序无法访问SQL SERVER的问题?
- 如何解决迅雷插件导致IE10崩溃的问题
- 如何解决UITextField挡住键盘的问题
- 教你如何将txt复制到excel的各个单元格;并解决科学计数法显示问题及导致的个位数变0问题