b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

IKeyBoardCallbackGlobalLayoutListenerTask用法postUI见AndroidKot

电脑杂谈  发布时间:2021-05-09 16:01:30  来源:网络整理

前言

众所周知,Google并未提供用于Android的官方API来监视软键盘的弹出和关闭。通常的做法是监视“活动”窗口的布局更改,以确定是否弹出/关闭软键盘。

代码实现

应注意,此处未使用ViewTreeObserver.OnGlobalLayoutListener来监视布局,但是将打开一个子线程以进行常规检查,因为在实际生产中发现onGlobalLayout()的刷新时间不确定。这与布局的复杂性有关,有时回叫一次可能需要2/3秒,依靠它来监视窗口的变化以确定弹出/关闭小键盘是否很酷。

在这里,我们将使用RxJava打开子线程,请参阅Android Kotlin基于RxJava的简单软件包,

android menu键_android 键盘关闭_oracle 关闭

获取一个循环播放器以连续检查窗口的更改,并在发生更改时吐出一个事件。

IKeyBoardCallback

interface IKeyBoardCallback {
    /**
     * 当键盘显示时回调
     */
    fun onKeyBoardShow()
    /**
     * 当键盘隐藏时回调
     */
    fun onKeyBoardHidden()
}

GlobalLayoutListenerTask

class GlobalLayoutListenerTask(private val activity: Activity) : SingleTask(){
    private val iKeyBoardCallbackList = mutableListOf()
    private var status = NONE
    private val interval = 100L
    /** 全屏时的高度 */
    private var fullScreenHeight = -1
    /** 状态栏高度 */
    private var statusBarHeight = -1
    override fun onTaskRun() {
        while (isRunning){
            try {
                //获取可视范围
                val rect = Rect()
                activity.window.decorView.getWindowVisibleDisplayFrame(rect)
                //获取屏幕高度
                val screenHeight = getFullScreenHeight(activity)
                //获取状态栏高度
                val statueHeight = getStatueBarHeight(activity)
                //获取被遮挡高度(键盘高度)(屏幕高度-状态栏高度-可视范围)
                val keyBoardHeight: Int = screenHeight - statusBarHeight - rect.height()
                //显示或者隐藏
                val isKeyBoardShow = keyBoardHeight >= screenHeight / 3
                //当首次或者和之前的状态不一致的时候会回调,反之不回调(用于当状态变化后才回调,防止多次调用)
                if (status == NONE || (isKeyBoardShow && status == HIDDEN) || (!isKeyBoardShow && status == SHOW)) {
                    if (isKeyBoardShow) {
                        status = SHOW
                        dispatchKeyBoardShowEvent()
                    } else {
                        status = HIDDEN
                        dispatchKeyBoardHiddenEvent()
                    }
                }
                Thread.sleep(interval)
            } catch (e: Exception){
                e.printStackTrace()
            }
        }
    }
    /**
     * 用于获取全屏时的整体高度
     *
     * @return 屏幕高度
     */
    private fun getFullScreenHeight(activity: Activity): Int {
        if (fullScreenHeight == -1){
            val vm = activity.windowManager
            fullScreenHeight = vm.defaultDisplay.height
        }
        return fullScreenHeight
    }
    /**
     * 用于获取状态栏高度
     *
     * @return 状态栏高度
     */
    private fun getStatueBarHeight(activity: Activity): Int {
        if (statusBarHeight == -1){
            val res = activity.resources
            val resId = res.getIdentifier("status_bar_height", "dimen", "android")
            statusBarHeight =  res.getDimensionPixelSize(resId)
        }
        return statusBarHeight;
    }
    /**
     * 添加回调
     *
     * @param callback 的回调类
     */
    fun addCallBack(callback: Any?){
        if (callback is IKeyBoardCallback)  iKeyBoardCallbackList.add(callback)
    }
    /**
     * 移除回调
     *
     * @param callback 的回调类
     */
    fun removeCallback(callback: Any?){
        if (callback is IKeyBoardCallback)  iKeyBoardCallbackList.remove(callback)
    }
    /**
     * 分发隐藏事件
     */
    private fun dispatchKeyBoardHiddenEvent(){
        for (callback in iKeyBoardCallbackList){
            callback.onKeyBoardHidden()
        }
    }
    /**
     * 分发显示事件
     */
    private fun dispatchKeyBoardShowEvent(){
        for (callback in iKeyBoardCallbackList){
            callback.onKeyBoardShow()
        }
    }
    /**
     * 判断是不是没有回调
     *
     * @return true:空 false:不空
     */
    fun isEmpty(): Boolean = iKeyBoardCallbackList.isEmpty()
    companion object {
        private const val NONE = 0;
        private const val SHOW = 1;
        private const val HIDDEN = 2;
    }
}

KeyBoardEventBus

object KeyBoardEventBus {
    private val taskCache: Hashtable = Hashtable()
    /**
     * 用于注册键盘,此方法适用于 View、Dialog、Fragement、FragementActivity、Activity
     *
     * @param obj 需要的类()
     */
    fun register(obj: Any?){
        val activity = getActivity(obj)
        if (activity == null){
            debug("register时获取activity失败!")
            return
        }
        register(activity, obj)
    }
    /**
     * 此方法区别于 {@link #register(Object)} ,之前的方法会限制注册的类型,当前的不会限制类型
     *
     * @param activity 宿主activity
     * @param obj   的类
     */
    fun register(activity: Activity, obj: Any?){
        if (obj == null) {
            debug("object为null!")
            return
        }
        var task = taskCache[activity]
        if (task == null){
            task = GlobalLayoutListenerTask(activity)
        }
        task.addCallBack(obj)
        if (!task.isEmpty()) task.start()
        taskCache[activity] = task
    }
    /**
     * 反注册
     *
     * @param obj 取消的类
     */
    fun unRegister(obj: Any?){
        //获取失败则直接停止,反之进行反注册
        val activity = getActivity(obj)
        if (activity == null){
            debug("unRegister时获取activity失败")
            return
        }
        unRegister(activity, obj)
    }
    /**
     * 反注册
     *
     * @param activity 宿主activity
     * @param obj 的类
     */
    fun unRegister(activity: Activity, obj: Any?){
        if ( obj == null) {
            debug("activity或object为null!")
            return
        }
        val task = taskCache[activity] ?: return
        task.removeCallback(obj)
        if (task.isEmpty()){
            task.cancel()
            taskCache.remove(task)
        }
    }
    /**
     * 获取对应View、Dialog、Fragment、FragmentActivity、Activity
     * (如果Object为null或者不是支持的类型则返回null)
     *
     * @param obj 需要获取的类
     * @return 返回对应的activity
     */
    private fun getActivity(obj: Any?): Activity?{
        if (obj == null) return null
        return when(obj){
            is View -> obj.context as Activity
            is Dialog -> obj.context as Activity
            is Fragment -> obj.activity
            is FragmentActivity -> obj
            is Activity -> obj
            else -> null
        }
    }
    /**
     * 用于打印信息
     *
     * @param msg 待打印的内容
     */
    private fun debug(msg: String){
        Log.e("KeyBoardEventBus",msg)
    }
}

用法

android menu键_android 键盘关闭_oracle 关闭

有关postUI,请参阅Android Kotlin代码说明,全局UI线程回调函数(基于扩展函数)

用于回调UI线程播放Toast

class MainActivity : AppCompatActivity(),IKeyBoardCallback {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        KeyBoardEventBus.register(this)
    }
    override fun onDestroy() {
        super.onDestroy()
        KeyBoardEventBus.unRegister(this)
    }
    override fun onKeyBoardShow() {
        postUI {
            Toast.makeText(this, "键盘显示",Toast.LENGTH_SHORT).show()
        }
    }
    override fun onKeyBoardHidden() {
        postUI {
            Toast.makeText(this, "键盘隐藏",Toast.LENGTH_SHORT).show()
        }
    }
}

完成工作


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-374201-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 方玉鹏
        方玉鹏

        肯定是这只学生放入去的

      • 李小璐
        李小璐

        如同2楼这种贪生怕死的人多半会是汉奸

      热点图片
      拼命载入中...