优雅的监听软键盘隐藏

Android 监听EditText输入框软键盘显示及隐藏 由于,安卓系统并没有提供软键盘弹入和弹出的方法。所以,我们需要自己自定义一个监听软件盘的类。大致实现原理就是监听视图树中布局或可视状态发生改变超过一定的数值,来监听软键盘的弹入弹出事件。 阅读详情

背景

  1. Android软键盘的显示和隐藏,从开始做直播这块,就一直困扰着我。
  2. 从布局挤压,到输入区显示不全,再到闪屏以及卡顿,这里的坑让我跌倒无数次。
  3. 各种布局监听,回调,代码冗余、复杂、与业务强耦合无法复用,还是没有很好的解决键盘的弹出和隐藏
  4. 为了给用户更好的操作体验,决定找到一种最优解决方案。

科普基础知识-WindowSoftInputMode

Activity 的主窗口与包含屏幕软键盘的窗口的交互方式。改属性的设置影响两个方面:

  • 当Activity成为用户注意的焦点时软键盘的状态-隐藏还是可见
  • 对Activity主窗口所做的调整-是否将其尺寸调小以为软键盘腾出空间,或者当窗口部分被软键盘遮挡时是否平移其那内容使当前焦点可见。

该设置必须是下标所列的值之一,或者一个state...值加上一个adjust...值的组合。在任一一组设置多个值(例如,多个state...值)都会产生未定义结果。各个值之间使用垂直条(|)分割。

值说明
stateUnspecified不指定软键盘的状态(隐藏还是可见)。 将由系统选择合适的状态,或依赖主题中的设置。这是对软键盘行为的默认设置。
stateUnchanged当 Activity 转至前台时保留软键盘最后所处的任何状态,无论是可见还是隐藏。
stateHidden当用户选择 Activity 时 — 也就是说,当用户确实是向前导航到 Activity,而不是因离开另一 Activity 而返回时 — 隐藏软键盘。
stateAlwaysHidden当 Activity 的主窗口有输入焦点时始终隐藏软键盘。
stateVisible在正常的适宜情况下(当用户向前导航到 Activity的主窗口时)显示软键盘。
stateAlwaysVisible当用户选择 Activity 时 — 也就是说,当用户确实是向前导航到 Activity,而不是因离开另一 Activity 而返回时 — 显示软键盘。
adjustUnspecified不指定 Activity 的主窗口是否调整尺寸以为软键盘腾出空间,或者窗口内容是否进行平移以在屏幕上显露当前焦点。 系统会根据窗口的内容是否存在任何可滚动其内容的布局视图来自动选择其中一种模式。 如果存在这样的视图,窗口将进行尺寸调整,前提是可通过滚动在较小区域内看到窗口的所有内容。这是对主窗口行为的默认设置。
adjustResize始终调整 Activity 主窗口的尺寸来为屏幕上的软键盘腾出空间
adjustPan不调整 Activity 主窗口的尺寸来为软键盘腾出空间, 而是自动平移窗口的内容,使当前焦点永远不被键盘遮盖,让用户始终都能看到其输入的内容。 这通常不如尺寸调正可取,因为用户可能需要关闭软键盘以到达被遮盖的窗口部分或与这些部分进行交互。

官方解释

网上解决方案

第一种方案

由于Activity.onKeyDownn()是监听不到向下的按键,所以自定义Edittext,重写onKeyPreIme方法

/**
 * 拦截键盘向下按键的 EditTextView
 */
public class TextEditTextView extends DmtEditText {
    public TextEditTextView(Context context) {
        super(context);
    }

    public TextEditTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextEditTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == 1 && onKeyBoardHideListener != null) {
            onKeyBoardHideListener.onKeyHide();
        }
        return super.onKeyPreIme(keyCode, event);
    }

    /**
     * 键盘监听接口
     */
    private OnKeyBoardHideListener onKeyBoardHideListener;

    public void setOnKeyBoardHideListener(OnKeyBoardHideListener onKeyBoardHideListener) {
        this.onKeyBoardHideListener = onKeyBoardHideListener;
    }

    public interface OnKeyBoardHideListener {
        void onKeyHide();
    }
}

为什么重写onKeyDown()方法,监听不到虚拟键的向下按键,而重写EditTextView的onKeyPreIme可以监听到,这篇博客写的很明白。

第二种方案

使用ViewTreeObserver.OnGlobalLayoutListener来监听整个布局的变化,但是有问题,点击软键盘的“向下”按键,不会回调这个函数。

View.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
 
    //当键盘弹出隐藏的时候会 调用此方法。
    @Override
    public void onGlobalLayout() {
        final Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        final int screenHeight = activity.getWindow().getDecorView().getRootView().getHeight();
        final int heightDifference = screenHeight - rect.bottom;
        boolean visible = heightDifference > screenHeight / 3;
        if(visible){
            Log.i(TAG,"软键盘显示");
        }else {
            Log.i(TAG,"软键盘隐藏");
        }
    }
});

第三种方案

将布局撑满全屏,来监听onMeasure()的变化,这种方式可以生效,但是和业务耦合性太大,而且在全面屏的时候处理比较麻烦,就不贴代码了

总结

基本上所有监听软键盘的方式,都是通过上面的三种方式实现的。实现效果比较好是Android键盘面板冲突 布局闪动处理方案

所有的方式都是在本页面上去弹起软键盘,软键盘是dialog,而且页面的逻辑和复杂程度有各种情况,非常难以考虑。真是让人抓耳挠腮呀。

打个响指,换种思路

没有非要在一个页面内完成软键盘的调度,我们可以另起炉灶,去实现这个功能。

使用DialogFragment来实现软键盘功能

这种情况还是与业务有一定的关联,我不敢说这种方案能够解决所有情况下的软键盘使用问题,但是能解决很多情况下的使用。

先说一下我的使用场景,因为我是负责直播模块的开发,软键盘的弹出和隐藏时的输入部分ui是不相同。使用抖音的直播举个例子

可以看到软键盘在打开和关闭的时候是不同的ui,那么就可以使用DialogFragment来实现功能。我们最主要实现就是监听软键盘的弹出和隐藏,弹出问题不大,这里最深的坑就是监听键盘的消失,先总结一下键盘消失的场景:

  1. 点击空白区域消失
  2. 点击虚拟键能向下按键隐藏键盘
  3. 点击软键盘向下按钮隐藏键盘
  4. 点击发送按钮后,消失键盘

ps: 2和3,看上去好像是一样的啊,大家肯定有一些疑惑,看图说话

从张图中可以清晰的看出来两者的区别,其实android的原生键盘是没有向下的按钮的,各个第三方的输入法自己实现的,andorid中没有回调可以监听到这个事件(坑爹啊)。而且
ViewTreeObserver 监听不到点击这个按钮时的布局变化(坑爹啊!!!),我只是在mix2手机上测试的,其他的手机类型我不敢确保也是同样的问题。

来来来,在做个小结:

  • 软键盘的弹出时可以监听的
  • 消失几种情况中,除了软键盘的向下按键其他都可以做到监听,或者可以拿到触发的时机。

搜了一大圈,好像没有找到比较好的解决方案,怎么办呢?但是别人家的直播都是可以做到的呀,这时看到了View.getWindowVisibleDisplayFrame()方法,来看下官方的解释

/**
     * Retrieve the overall visible display size in which the window this view is
     * attached to has been positioned in.  This takes into account screen
     * decorations above the window, for both cases where the window itself
     * is being position inside of them or the window is being placed under
     * then and covered insets are used for the window to position its content
     * inside.  In effect, this tells you the available area where content can
     * be placed and remain visible to users.
     *
     * <p>This function requires an IPC back to the window manager to retrieve
     * the requested information, so should not be used in performance critical
     * code like drawing.
     *
     * @param outRect Filled in with the visible display frame.  If the view
     * is not attached to a window, this is simply the raw display size.
     */
    public void getWindowVisibleDisplayFrame(Rect outRect) {
        if (mAttachInfo != null) {
            try {
                mAttachInfo.mSession.getDisplayFrame(mAttachInfo.mWindow, outRect);
            } catch (RemoteException e) {
                return;
            }
            // XXX This is really broken, and probably all needs to be done
            // in the window manager, and we need to know more about whether
            // we want the area behind or in front of the IME.
            final Rect insets = mAttachInfo.mVisibleInsets;
            outRect.left += insets.left;
            outRect.top += insets.top;
            outRect.right -= insets.right;
            outRect.bottom -= insets.bottom;
            return;
        }
        // The view is not attached to a display so we don't have a context.
        // Make a best guess about the display size.
        Display d = DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
        d.getRectSize(outRect);
    }

大概意思:这个api是用来获取窗口可视区域大小的。该大小会收到系统状态栏、软键盘和虚拟按键的影响。在应用开发中可以利用该api来获取状态栏的高度,软键盘的高度和虚拟按键的高度。

解决方案:
既然没有回调能够拿到虚拟键盘的向下操作,那么我们就轮询监听窗口的大小,由于这个dialogFragment的生命周期只是在输入的时候存在,那么就以为这这个轮询时间也不会太长,100ms轮询一次来监听窗口变化的大小,完美解决(如果还有其他优雅的解决方案,请告诉我)。

用DialogFragment实现输入区域的好处:

  1. 输入部分的逻辑与其他业务本分的逻辑隔离,实现解耦
  2. DialogFragment也是一个dialog,可以单独处理键盘弹出时的逻辑

有了以上两点考虑,我就开始动手写代码

Version 1

源代码就不贴了,太长了,而且大部分和业务相关,所有的业务逻辑和功能逻辑全部写在DialogFragment中,看上去没什么问题,如果突然有一天,另外的一个地方要做到类似的逻辑,又要重新写一遍功能逻辑,完全不能复用呀,这样的实现方案是不行的,打回去重做。嗯,需要将业务逻辑和功能逻辑分割开,这样可以很大程度上的复用当前代码。

Version 2

首先要定义一个接口,来定义此类功能的统一调用方式,所有要实现此功能的类都要实现这个接口

public interface IKeyBoard {

    // EditTextView需要继承TextEditTextView,TextEditTextView是用来监听虚拟按键向下的操作
    TextEditTextView getEditTextView();

    // 根布局
    View getRoot();

    // dialogFragment 销毁时调用,也就是隐藏时
    void onDismiss();
}

自定义EditTextView

/**
 * 拦截键盘向下按键的 EditTextView
 */
public class TextEditTextView extends DmtEditText {
    public TextEditTextView(Context context) {
        super(context);
    }

    public TextEditTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextEditTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == 1 && onKeyBoardHideListener != null) {
            onKeyBoardHideListener.onKeyHide();
        }
        return super.onKeyPreIme(keyCode, event);
    }

    /**
     * 键盘监听接口
     */
    private OnKeyBoardHideListener onKeyBoardHideListener;

    public void setOnKeyBoardHideListener(OnKeyBoardHideListener onKeyBoardHideListener) {
        this.onKeyBoardHideListener = onKeyBoardHideListener;
    }

    public interface OnKeyBoardHideListener {
        void onKeyHide();
    }
}

最主要的类来了:

/**
 * 这个类时用来实现输入框随软键盘弹出的情况,这个dialogFragment只负责弹起键盘的操作,不负责具体的ui显示和逻辑,
 * 应该实现一个UI类来实现相应的显示和逻辑部分。
 * <p>
 * 使用方法:
 * 1. 需要实现{@link IKeyBoard}
 * 2. UI类需要包含{@link TextEditTextView}
 * 3. 如果UI需要监听声明周期,需要实现{@link LifecycleObserver}
 * <p>
 * ps:父类的Fragment或者Activity  window的setSoftInputMode设置为{@link WindowManager} SOFT_INPUT_ADJUST_NOTHING
 *
 * @author liyachao
 * @date 2018/4/17
 */

public class KeyBoardDialogFragment extends DialogFragment implements TextEditTextView.OnKeyBoardHideListener,
        WeakHandler.IHandler {
    private static final String TAG = "KeyBoardDialogFragment";

    private IKeyBoard mKeyBoardView;
    private TextEditTextView mTextEditTextView;
    private boolean softKeyBoardIsVisible;
    private Activity mActivity;
    private WeakHandler mHandler;
    private Rect mRect = new Rect();


    public static KeyBoardDialogFragment newInstance(IKeyBoard keyBoard) {
        KeyBoardDialogFragment fragment = new KeyBoardDialogFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        fragment.setKeyBoardView(keyBoard);
        return fragment;
    }

    /**
     * 安全检查
     * @param keyBoardView 业务逻辑的view
     */
    public void setKeyBoardView(IKeyBoard keyBoardView) {
        if (keyBoardView == null) {
            throw new RuntimeException("keyBoardView must not be null");
        } else if (keyBoardView.getEditTextView() == null) {
            throw new RuntimeException("keyBoardView must has EditTextView");
        } else if (keyBoardView.getRoot() == null) {
            throw new RuntimeException("keyBoardView must has root layout");
        }
        mKeyBoardView = keyBoardView;
        mTextEditTextView = keyBoardView.getEditTextView();
    }

    /**
     * 设置主题 input_dialog_style_large的具体设置如下
     * <style name="input_dialog_style_large" parent="@android:style/Theme.Dialog">
     *         <item name="android:windowBackground">@color/transparent</item> //winndow 背景为透明色 
     *         <item name="android:windowNoTitle">true</item> // 没有title
     *         <item name="android:backgroundDimEnabled">false</item> // 没有默认的背景色
     *         <item name="android:windowAnimationStyle">@style/keyboard_dialog_animation</item> //window动画,可以不设置
     *     </style>
     * 业务逻辑view,注册DialogFragment声明周期
     * 
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(STYLE_NO_TITLE, R.style.input_dialog_style_large);
        if (mKeyBoardView == null || mKeyBoardView.getRoot() == null) {
            dismiss();
            return;
        }
        if (mKeyBoardView.getRoot() instanceof LifecycleObserver) {
            getLifecycle().addObserver((LifecycleObserver) mKeyBoardView.getRoot());
        }
        mHandler = new WeakHandler(this);
    }


    @Override
    public void onAttach(Context activity) {
        super.onAttach(activity);
        mActivity = (Activity) activity;
    }


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return mKeyBoardView.getRoot();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mTextEditTextView.setOnKeyBoardHideListener(this);
        initWindowParams();
    }

    /**
     * 设置window属性
     */
    public void initWindowParams() {
        Window window = getDialog().getWindow();
        if (window == null) {
            return;
        }
        WindowManager.LayoutParams lp = getDialog().getWindow().getAttributes();
        lp.dimAmount = 0;
        lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
        lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
        lp.gravity = Gravity.BOTTOM;
        window.setBackgroundDrawable(new ColorDrawable(0));
        window.setAttributes(lp);
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.setCanceledOnTouchOutside(true);
        return dialog;
    }

    @Override
    public void onResume() {
        super.onResume();
        mHandler.sendEmptyMessageDelayed(1, 100);
    }

    @Override
    public void onStop() {
        super.onStop();
        dismissAllowingStateLoss();
        mHandler.removeMessages(1);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        mKeyBoardView.onDismiss();
    }

    @Override
    public void onKeyHide() {
        dismiss();
    }

    public void onGlobalLayout() {
        Window window = getDialog().getWindow();
        if (window != null) {
            mRect.setEmpty();
            window.getDecorView().getWindowVisibleDisplayFrame(mRect);
            int screenHeight = UIUtils.getScreenHeight(getContext());
            int heightDifference = screenHeight - (mRect.bottom - mRect.top);
            if (heightDifference > screenHeight / 3) {
                Log.d(TAG, "键盘弹出");
                softKeyBoardIsVisible = true;
            } else {
                if (softKeyBoardIsVisible) {
                    Log.d(TAG, "键盘隐藏");
                    dismiss();
                    softKeyBoardIsVisible = false;
                }
            }
        }
    }

    @Override
    public void handleMsg(Message msg) {
        if (msg.what == 1) {
            onGlobalLayout();
            mHandler.sendEmptyMessageDelayed(1, 100);
        }
    }
}

具体的实现就是上面了,大部分做了注释,也不需要解释了,基本上可以解决大部分场景,可以根据自己具体的业务逻辑做一些改动。demo就不给大家了,上面基本上就可以了。

demo下载

Android Dialog与软键盘的正确打开方式 博客地址:http://blog.youkuaiyun.com/kong_gu_you_lan/article/details/54880073 立即下载

相关推荐

STM32F4与LAN8720硬件连接避坑指南:从原理图到RMII信号完整性的实战解析

本文深入解析了STM32F4与LAN8720以太网连接的硬件设计要点与常见陷阱。重点剖析了电源上电时序、复位电路设计、RMII接口配置等关键环节,并提供了从原理图设计到PCB布局、信号完整性调试的完整实战指南,帮助硬件工程师规避设计风险,确保以太网通信的长期稳定运行。

weixin_29189003的博客 211

DialogFragment自动弹出软键盘,消失时关闭软键盘

在DialogFragment显示时弹出软键盘在DialogFragment消失时关闭软键盘

MingYang 1649

【WILEY】从Revision到Online:逐层拆解投稿状态更新与关键文件提交实战

本文详细解析了学术论文从返修到在线发表的全过程,重点拆解了投稿系统状态更新背后的含义与应对策略。文章提供了返修稿与回复信的准备技巧、关键补充文件(如图文摘要)的提交要点,并分享了校对校样与处理出版协议的实战经验,帮助作者高效、专业地完成发表流程。

weixin_29209805的博客 711

DialogFragment全屏及软键盘自动弹出

1. DialogFragment全屏设置DialogFragment全屏:@Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setStyle(DialogFragm

Flying Cat 8985

RT-DETR改进策略【模型轻量化】| 替换骨干网络为 2024轻量化网络MoblieNetV4:移动生态系统的通用模型

本文记录的是基于MobileNet V4的RT-DETR目标检测轻量化改进方法研究。通过整合UIBMobile MQA以及优化的NAS策略能够在在不降低性能指标的前提下,降低计算成本。本文配置了原论文中和五种模型,以满足不同的需求。

Limiiiing的博客 1922

架构师之HBase vs MongoDB 技术选型与场景决策实战案例

面对海量数据和高并发查询,该选 HBase 还是 MongoDB?本文为你提供完整的决策框架!从数据模型对比、架构解析、六大真实场景(电信 CDR、金融行情、广告点击流、电商商品、社交档案、内容管理)到性能、一致性、运维全面对比,助你在 PB 级时序数据和灵活查询之间做出精准选择!

肖哥弹架构博客 1097

Android Dialog软键盘弹出问题完美解决办法

Android Dialog软键盘弹出问题完美解决办法。

陌sr丶的博客 1609

使用 Tesseract 在 C# 中进行光学字符识别(OCR)

你可以根据需要对 Tesseract 进行自定义配置,例如设置识别的分辨率、识别模式等。// 只识别数字// 设置自定义变量本文只讲述了简单的使用方法,未涉及字库训练,识别的准确率与训练的字库有关。

仰望星空的博客 4730

Android 弹出Dialog的时候如何弹出软键盘(输入法)

corners_14_color_white_stroke_1_color_80000000的drawable文件。corners_14_color_white_stroke_1_color_blue的drawable文件。2、在弹出Dialog的时候弹出软键盘(这里是自定义的Dialog,普通的Dialog也是一样的)。4、在res文件夹的drawable文件夹新建几个xml文件,并把一下的xml代码复制进去。corners_14_color_white的drawable文件。1、写一个软键盘管理类。

UrasakiNakajima的博客 3249

大数据预测分析:精准把握市场趋势

传统市场预测多依赖经验判断(比如“去年卖了1000件,今年加20%”)或小数据统计(比如用近6个月的销量做线性回归)。而大数据预测分析是:利用海量结构化+非结构化数据(销售、用户、社交媒体、天气等),通过机器学习/深度学习模型,挖掘数据中的关联关系与趋势规律,实现对未来市场走势的精准预测。更全面:覆盖内部(企业数据)+外部(行业、环境数据)的全维度数据;更精准:用算法替代人工,避免主观偏差;更实时:支持分钟级/小时级的实时预测(比如直播带货的销量预测)。错误做法。

AI智能探索者的博客 1024

SAP-ABAP:接口多继承与复合接口设计:复杂业务场景下的能力组合实现方案

本文介绍了ABAP中通过接口多继承与复合接口设计实现能力组合的方案。文章首先辨析了类实现多个接口与接口继承接口的核心概念,指出ABAP虽不支持类多继承,但可通过这两种机制灵活组合能力。随后详细讲解了类实现多个接口的语法规则与三种调用方式,并给出了五个基础能力接口的设计示例(日志记录、权限校验、数据导出、消息通知、格式转换)。作者通过对比单继承与接口多重实现的差异,强调后者在解耦和扩展性上的优势,为复杂业务场景下的能力组合提供了实用解决方案。

baidu_35680696的博客 244

Android 通过点击EditText之外的地方隐藏软键盘

我们都知道当点击EditText的时候,会自动弹出软键盘,但是如何实现点击屏幕其他地方就隐藏它呢? 现在大部分聊天软件,如微信之类的都有这个效果,感觉用户体验很不错,刚好最近有个项目要用到这个,查了些资料,这里也分享下。         先创建个工具类吧。 public class HideSoftKeyboard {        public static void hideSoftKeyboa

qq_36341161的博客 345

基于OpenClaw的自动化文件管理与文档分类系统设计与实现

本文介绍了一种基于OpenClaw的自动化文件管理与文档分类系统。系统采用三层架构设计,包含数据层、逻辑层和应用层,核心组件涵盖文件扫描、处理、分类、移动等功能。技术选型上使用Python/FastAPI作为后端,结合PostgreSQL/Elasticsearch/MinIO存储方案,并整合scikit-learn/PyTorch等AI技术实现智能分类。系统实现了文件递归扫描、增量扫描、元数据提取等功能,通过文件哈希和修改时间检测变化。该方案能有效提升文件管理效率,实现文档的自动化分类与智能管理。

一键难忘的博客 753

在android中如何通过点击edittext之外的部分使软键盘隐藏

  我们知道在android中点击edittext框就会自动弹出软键盘,那怎么通过点击edittext之外的部分使软键盘隐藏呢?(微信聊天时的输入框就是这个效果,这个给用户的体验还是很不错的)   首先我们要先定义一个隐藏软键盘的工具类方法:  1 public static void hideSoftKeyboard(Activity activity) { 2 In...

diaoqi5743的博客 244

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

引入软键盘事件监听的福音:KeyboardVisibilityEvent 开源库

在我们的日常开发中,处理软键盘的显示和隐藏总是让人头疼的。不过,今天我将为大家介绍一款能够高效管理软键盘可见性变化的优秀Android库——**KeyboardVisibilityEvent**。 ## 项目介绍 **KeyboardVisibilityEvent**是一款成熟稳定的Android库,它能完美应对软键盘显示状态的变化,提供了一套简洁高效的API来检测软键盘的状态,并且提供了显示...

gitblog_00599的博客 742

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

如何在 UISearchBar 中优雅地收起软键盘?

首先需要说明,第三方的键盘管理工具,IQKeyboardManager 无法应用到 UISearchBar 中。要让 IQKeyboardManager 能够应用到 UISearchBar 上,你需要修改 IQUIView+Hierarchy.m 的 - (void)isSearchBarTextField 方法。这一点在 stackoverflow 上已经有人讨论过了。这种解决方法离“优雅”二字...

kmyhy的专栏 2184

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【开源精粹】Linux下的 Qt 魔法:一款优雅软键盘

【开源精粹】Linux下的 Qt 魔法:一款优雅软键盘 去发现同类优质开源项目:https://gitcode.com/ 项目介绍 在数字化时代的浪潮中,人机交互的便捷性日益成为软件开发的重点。针对Linux环境,有一款基于Qt框架打造的软键盘脱颖而出——它不仅仅是一个工具,更是一种提升用户体验的艺术品。通过简洁的设计与高效的实用性,这款软键盘旨在为Linux用户提供无与伦比的输入体验,无论是日常...

gitblog_09718的博客 852

android-如何优雅的在软键盘上方加入自定义布局

isOpen true 弹起 ,false 收起。控制显示隐藏需要顶起的布局。windowSoftInputMode 属性,如果嵌套Fragment,则需要设置对应。如果遇到,系统虚拟导航遮挡和不能设置透明导航栏处理的问题,请参考如下文章链接;2,第二步,监听软键盘的弹起与隐藏。话不多说直接上思路。

Snow_亮 博客 315

android 软键盘遮挡登陆按钮的问题,Android优雅的方式解决软键盘遮挡按钮问题

前言比如在进行登录的操作中,用户输入完密码之后,肯定是想直接点击登录按钮的。返回键隐藏软键盘这样的体验肯定很糟糕,程序员,遇到问题解决问题。实现1xmlandroid:id="@+id/scrollview"android:layout_width="match_parent"android:layout_height="wrap_content"android:fadingEdge="none"...

weixin_33751984的博客 401

软键盘 显示隐藏 测量高度 MD

Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com 目录 目录软键盘相关问题设置 OnLayoutChangeListener ...

weixin_30419799的博客 139

Android 键盘监听 键盘展开/收起监听

如何优雅地实现 Android 键盘展开与收起的实时监听

光年的博客 4100

推荐开源项目:Android软键盘最佳解决方案

推荐开源项目:Android软键盘最佳解决方案 soft-input-eventAndroid软键盘遮挡/平滑动画最佳解决方案 Solution for keyboard cover in/smooth animation项目地址:https://gitcode.com/gh_mirrors/so/soft-input-event 在Android开发中,处理软键盘的显示与隐藏往往是一个棘手的问...

gitblog_00032的博客 769

推荐开源项目:KeyboardVisibilityEvent - 智能处理软键盘可见性变化的Android库

在Android开发中,处理软键盘的显示与隐藏常常是一个棘手的问题,尤其是在布局交互设计中。现在,有了[KeyboardVisibilityEvent](https://github.com/yshrsmz/KeyboardVisibilityEvent),这一切变得轻松简单。这个小巧而强大的库,旨在帮助开发者监听和管理Android设备上软键盘的可见状态,并提供了方便的方法来控制其显示和隐藏。 ...

gitblog_00028的博客 539

Android开发者的福音:软键盘处理新星——`Soft-Input-Event`框架深度剖析

Android开发者的福音:软键盘处理新星——Soft-Input-Event框架深度剖析 在Android应用开发中,软键盘的管理历来是让人头疼的问题之一。它不仅关系到用户体验的细腻程度,还直接关联着界面布局的复杂调整。不过,随着Soft-Input-Event框架的出现,这些问题似乎找到了一种更为优雅和高效的解决方案。让我们一起深入了解这一开源宝藏,探索它的魅力所在。 项目介绍 Soft-In...

gitblog_00027的博客 826

Android软键盘管理神器:SoftKeyboardUtil 使用指南

Android软键盘管理神器:SoftKeyboardUtil 使用指南 项目介绍 SoftKeyboardUtil 是一个专为简化Android平台中软键盘与编辑框(EditText)交互而设计的轻量级库。通过极简的API调用,开发者能够高效地控制软键盘的显示隐藏、检测软键盘的高度变化,以及处理相关交互逻辑。该项目由 GitHub 用户 zybieku 开发并维护,遵循Apache-2.0许可...

gitblog_00674的博客 607

android 软键盘遮挡登陆按钮的问题,Android优雅的方式解决软键盘遮挡按钮

前言比如在进行登录的操作中,用户输入完密码之后,肯定是想直接点击登录按钮的。返回键隐藏软键盘这样的体验肯定很糟糕,程序员,遇到问题解决问题。实现1xmlandroid:id="@+id/scrollview"android:layout_width="match_parent"android:layout_height="wrap_content"android:fadingEdge="none"...

weixin_32653933的博客 226
上一篇: Retrofit2源码阅读
下一篇: 优雅的使用Kotlin
Bobby_lyc
博客等级 码龄16年 1164粉丝 89原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值