android 聊天界面键盘、表情切换丝滑

1、我们在聊天页面时候,往往会遇到,键盘、表情、其他选择切换时候页面会出现掉下来再弹起问题,这是因为,我们切换时候,键盘异步导致内容View高度变化,页面掉下来后,又被其他内容顶起这种很差视觉效果。

要解决这个问题,最简单方法就是切换时候,将内容View高度固定然后去操作键盘显示后再去释放内容View高度。

2、这里我们提供具体思路

2.1xml布局:(FrameLayout + RecyclerView,是为了让键盘弹起时候,RecyclerView有个向上平移效果)

复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!--  标题View -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize">



    </androidx.constraintlayout.widget.ConstraintLayout>


    <!--  聊天展示View   android:layout_weight="1" 让聊天内容填充剩下内容-->
    <com.scwang.smart.refresh.layout.SmartRefreshLayout
        android:id="@+id/smartRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:srlEnableLoadMore="false"
        app:srlEnableRefresh="true">

 <!--  添加FrameLayout 是为了让键盘弹起时候,聊天内容(RecyclerView)平移上去效果-->
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyler"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="bottom"
                android:overScrollMode="never"
                android:scrollbars="none"
                android:visibility="invisible" />

        </FrameLayout>


    </com.scwang.smart.refresh.layout.SmartRefreshLayout>

    <!-- 按钮:发送、输入框等View -->
    <LinearLayout
        android:id="@+id/button_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


    </LinearLayout>

    <!-- 图片选择、语音、视频等View -->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/other_select"
        android:layout_width="match_parent"
        android:layout_height="@dimen/common_dp_114"
        android:visibility="gone">



    </androidx.constraintlayout.widget.ConstraintLayout>

    <!-- emotion 表情选择View  这个是自定义View-->
    <EmotionView
        android:id="@+id/emotion"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" />

</LinearLayout>

2.2:当键盘需要弹起锁内容View高度(这里重点讲解参数:height,height = smartRefreshLayoutMaxHeight(聊天内容最大高度) - supportSoftInputHeight(键盘的高度),这样做的目前就是让键盘弹起时候,页面感觉聊天内容View平移上效果)

复制代码
 private void viewLockHeight(int height) {
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) smartRefreshLayout.getLayoutParams();
        layoutParams.height = height == 0 ? smartRefreshLayout.getHeight() : height;
        layoutParams.weight = 0.0F;
        smartRefreshLayout.setLayoutParams(layoutParams);
    }

2.3:延迟释放高度(设置 layoutParams.weight = 1.0F)

复制代码
 private void viewReleaseLockHeight(int delayMillis) {
        if (smartRefreshLayout != null) {
            smartRefreshLayout.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (smartRefreshLayout != null) {
                        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) smartRefreshLayout.getLayoutParams();
                        layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT;
                        layoutParams.weight = 1.0F;
                        smartRefreshLayout.setLayoutParams(layoutParams);
                    }
                }
            }, delayMillis == 0 ? 200L : delayMillis);
        }
    }

2.4:RecyclerView展示最后一条数据(切换、键盘、表情等)

复制代码
  public void recyclerStopScroll() {
        recyclerView.stopScroll();
        layoutManager.scrollToPositionWithOffset(0, 0);
    }

3:切换流程

界面正常展示(此时聊天内容界面最大高度展示)--->弹起键盘

①、RecyclerView停止所有事件recyclerStopScrol()

②、内容View锁高 viewLockHeight(contentViewMaxHeight)

③、起键盘

④、延迟释放高度viewReleaseLockHeight()

弹起键盘------>表情

①、RecyclerView停止所有事件recyclerStopScrol()

②、内容View锁高 viewLockHeight(0)

③、收键盘

④、展示表情

⑤、延迟释放高度viewReleaseLockHeight()

表情------>弹起键盘

①、RecyclerView停止所有事件recyclerStopScrol()

②、内容View锁高 viewLockHeight(0)

③、弹起键盘

④、收起表情

⑤、延迟释放高度viewReleaseLockHeight()

相关推荐
Kapaseker1 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴1 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭11 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab12 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe18 小时前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋1 天前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我2 天前
让我们实现一个更好看的内部阴影按钮
android·flutter