软键盘弹出顶起布局的小技巧

在安卓开发中我们会很频繁的和软键盘打交道,但是软键盘本来是不属于我们的布局的,它的出现会遮挡布局,比如,布局中有一个EditText是位于底部的,点击之后弹出软键盘,如果我们不做任何处理,那软键盘必然会将EditText遮挡,这是很糟糕的效果,该怎么避免呢?

首先我想到了Activity的windowSoftInputMode属性,这个属性能影响两件事情: 
1、当有焦点产生时,软键盘是隐藏还是显示 
2、是否改变活动主窗口大小以便腾出空间展示软键盘 
它有以下值可以设置: 
1、stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置 
2、stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示 
3、stateHidden:用户选择activity时,软键盘总是被隐藏 
4、stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的 
5、stateVisible:软键盘通常是可见的 
6、stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态 
7、adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示 
8、adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间 
9、adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖,并且用户总能看到输入内容的部分 
可以设置一个或多个,多个之间用|分开。这些值中符合我们要求的是adjustResize和adjustPan。先看adjustPan,它会将当前获取了焦点的EditText之上的布局整体上移,以此来达到EditText不被软键盘覆盖的目的。但如果我只想让EditText和与EditText有关的一些控件上移,而它们之上的控件保持不变呢?OK,这时候我们就需要用到adjustResize,但是光用它还是不够的,还需要我们的布局配合。

我的需求如下: 
1、布局的上半部分放一个视频播放器,可以实现简单的视频播放功能; 
2、布局的下半部分有包括EditText在内的布局 
3、点击EditText,要求包括EditText在内的布局均被软键盘顶起,而视频播放的布局不被挤压

实现效果如下 

这里写图片描述

直接上代码:
1、在清单文件中给相应的Activity设置windowSoftInputMode属性

        <activity
            android:name=".activity.VideoPublishActivity"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustResize|stateHidden" />

2、布局文件

<?xml version="1.0" encoding="utf-8"?>
//最外层必须是RelativeLayout,才能保证布局被顶起
<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:background="#fff"
    tools:context="com.daishu.copperman.activity.VideoPublishActivity">
    //软键盘弹出时,这个布局不动,且视频播放正常,不被挤压变形
    //这层套FrameLayout是为了防止播放视频的布局被挤压
    <FrameLayout 
        android:id="@+id/fl_video_play"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/rl_title">
        //我在这里动态添加了播放器
        <RelativeLayout 
            android:id="@+id/rl_video_play"
            android:layout_width="match_parent"
            android:layout_height="360dp"
            android:background="#f2f2f2">
        </RelativeLayout>
    </FrameLayout>
    //以下是需要被软键盘顶起的布局
    <LinearLayout
        android:id="@+id/ll_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" //想要顶起的布局必须居于底部
        android:background="#fff"
        android:orientation="vertical">

        <EditText
            android:id="@+id/et_publish_title"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="@null"
            android:gravity="start"
            android:hint="请输入标题(30字以内)" />

        <com.zhy.view.flowlayout.TagFlowLayout
            android:id="@+id/id_flowlayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="15dp"
            zhy:max_select="1" />

        <Button
            android:id="@+id/btn_publish"
            style="?android:attr/borderlessButtonStyle"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:background="@drawable/shape_publish_btn"
            android:gravity="center"
            android:text="发布"
            android:textColor="#2e2e2e"
            android:textSize="14sp" />
    </LinearLayout>
 </RelativeLayout>

我们总结一下(敲黑板!划重点!): 
1、最外层布局必须是相对布局RelativeLayout(保证只顶起部分布局,而不是将整个界面上移); 
2、需要在承载视频播放器的布局外套一层FrameLayout(保证布局顶起时视频不被挤压); 
3、将想要顶起的布局居于底部(保证此部分布局被全部顶起);

做到这三点就可以简单实现软键盘弹出,将布局顶起,且不挤压视频播放的效果了。

添加一个想法:

如不想将控件的高度写死,有可能需要动态设置高度,那么可能要用到如下方法:

/**
 * 获取屏幕高度
 *
 * @return 返回屏幕高度
 */
private int getDisplayHeight() {
    DisplayMetrics dm = getResources().getDisplayMetrics();
    return dm.heightPixels;
}

/**
 * 获取状态栏高度
 *
 * @return 返回状态栏高度
 */
private int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

这里我们用到了getIdentifier()的方法来获取资源的ID,其中第一个参数是要获取资源对象的名称,比如我们要获取状态栏的相关内容,这里填入"status_bar_height";第二个参数是我们要获取什么属性,我们要获取高度内容,所以填入"dimen";第三个是包名,状态栏是系统内容,故填入“android”。

另外一个用到的办法是getDimensionPixelSize(),由函数名就能知道是根据资源ID获得资源像素尺寸,这里就直接获得状态栏的高度。

这种方法在状态栏不存在的时候就会获得其高度为0.

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值