Android UI设计系列之自定义ViewGroup打造通用的关闭键盘小控件ImeObserverLayout(9)

让我来详细讲解一下“Android UI设计系列之自定义ViewGroup打造通用的关闭键盘小控件ImeObserverLayout(9)”的完整攻略。

简介

本篇攻略主要是讲解如何自定义ViewGroup来实现通用的关闭键盘小控件ImeObserverLayout。通过本文的学习,你将会了解到如何使用较少的代码实现一个通用的小控件,并掌握自定义ViewGroup的基本知识。

步骤

本篇攻略的步骤分为以下几个部分:

  1. 准备工作
  2. 继承RelativeLayout实现ImeObserverLayout
  3. 布局设计
  4. 代码实现
  5. 示例演示

1. 准备工作

在开始之前,我们需要了解一下自定义ViewGroup的基本概念和使用方法。可以先去查看一下官方文档,了解一下相关知识。

2. 继承RelativeLayout实现ImeObserverLayout

在这里,我们使用RelativeLayout作为基类,继承它来实现我们的ImeObserverLayout。

public class ImeObserverLayout extends RelativeLayout {

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

    ...
}

3. 布局设计

我们的布局需要包含两部分,一部分是要使用该控件的页面布局,另一部分则是一个用于拦截弹出键盘事件的view。

<com.example.ImeObserverLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/input_holder">

    <!-- 布局代码 -->

    <com.example.ImeObserverLayout.ObserveKeyBoardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/observe_keyboard" />

</com.example.ImeObserverLayout>

其中,ObserveKeyBoardView是继承自View的一个自定义类,目的是用来拦截并消费弹出键盘的事件。

4. 代码实现

在这里,我们需要实现一些方法,来监听键盘的弹出与隐藏事件,并根据这些事件来进行相应的操作。在这里,我写了五个方法,分别是onTouchEvent、onInterceptTouchEvent、onSizeChanged、dispatchKeyEvent和onLayout。这些方法具体实现可以参见完整的代码,这里不再赘述。

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
        if (isShown()) {
            hideIme();
        }
    }
    return super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
        if (isInputMethodActive(getContext())) {
            hideIme();
        }
    }
    return super.onInterceptTouchEvent(ev);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    if (w == oldw && h == oldh) {
        return;
    }
    if (oldh > h) {
        if (isInputMethodActive(getContext())) {
            hideIme();
        }
    }
}

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
        if (isInputMethodActive(getContext())) {
            hideIme();
            return true;
        }
    }
    return super.dispatchKeyEvent(event);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    if (changed) {
        hideIme();
    }
}

public static boolean isInputMethodActive(Context context) {
    InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    if (inputMethodManager != null) {
        return inputMethodManager.isActive();
    }
    return false;
}

public void hideIme() {
    InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    if (inputMethodManager != null) {
        inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
    }
}

5. 示例演示

在代码实现完成之后,我们需要进行示例演示,来验证我们的代码是否能够正常工作。以下是两个简单的示例:

示例一

在这个示例中,我们使用ImeObserverLayout来包裹一个EditText,并且在xml中直接设置android:focusable="true" 和android:focusableInTouchMode="true"属性。

<com.example.ImeObserverLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/input_holder">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/input_area"
        android:hint="@string/input_hint"
        android:inputType="text"
        android:focusable="true"
        android:focusableInTouchMode="true"/>

    <com.example.ImeObserverLayout.ObserveKeyBoardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/observe_keyboard" />

</com.example.ImeObserverLayout>

在代码中,我们需要找到input_holder和observe_keyboard两个view,并设置ImeObserverLayout。代码如下:

ImeObserverLayout container = findViewById(R.id.input_holder);
ImeObserverLayout.ObserveKeyBoardView observerView = findViewById(R.id.observe_keyboard);

container.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is hidden", Toast.LENGTH_SHORT).show());
observerView.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is shown", Toast.LENGTH_SHORT).show());

以上代码设置了输入框弹出键盘和关闭键盘的回调方法,并实现Toast的提示。

示例二

在这个示例中,我们使用ScrollView来包裹ImeObserverLayout,并添加一个Button来触发弹出键盘。

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/input_holder">

    <com.example.ImeObserverLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/input_holder2">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/btn_show_keyboard"
                android:id="@+id/show_keyboard"/>

            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/input_area2"
                android:hint="@string/input_hint"
                android:inputType="text"/>

        </LinearLayout>

        <com.example.ImeObserverLayout.ObserveKeyBoardView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/observe_keyboard2" />

    </com.example.ImeObserverLayout>

</ScrollView>

在代码中,我们需要找到show_keyboard并设置点击事件,用于触发键盘弹出,同样实现了弹出键盘和关闭键盘的回调方法。

Button showKeyboardButton = findViewById(R.id.show_keyboard);
showKeyboardButton.setOnClickListener(v -> {
    EditText inputArea2 = findViewById(R.id.input_area2);
    inputArea2.requestFocus();
    InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.showSoftInput(inputArea2, InputMethodManager.SHOW_IMPLICIT);
});
ImeObserverLayout container2 = findViewById(R.id.input_holder2);
ImeObserverLayout.ObserveKeyBoardView observerView2 = findViewById(R.id.observe_keyboard2);
container2.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is hidden", Toast.LENGTH_SHORT).show());
observerView2.setListener(() -> Toast.makeText(MainActivity.this, "Keyboard is shown", Toast.LENGTH_SHORT).show());

总结

通过本篇攻略的学习,我们掌握了如何自定义ViewGroup来实现通用的关闭键盘小控件ImeObserverLayout并学习了自定义VIewGroup的基本知识。我们通过示例的方式来验证代码的正确性,相信你现在已经了解了如何使用自定义ViewGroup来实现一个小控件,希望本篇攻略对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android UI设计系列之自定义ViewGroup打造通用的关闭键盘小控件ImeObserverLayout(9) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • BBSMAX

    BBSMAX BBSMAX是一款开源的论坛软件,它具有丰富的论坛功能和可定制性。在使用过程中,用户可以轻松地创建自己的社区,并为社区的设计和功能进行自定义。 功能特点 BBSMAX具有许多先进的功能,包括但不限于: 完善的内容管理系统,包括帖子、评论、私信、通知等 支持多种主题皮肤,允许用户自定义网站外观和风格 内置的用户管理系统,允许管理员轻松管理用户、版…

    其他 2023年3月28日
    00
  • 路由器常见内存容量说识别

    路由器常见内存容量识别攻略 路由器常见内存容量识别是一项重要的技能,它可以帮助我们了解路由器的性能和适用场景。下面是一个详细的攻略,帮助你识别路由器的常见内存容量。 步骤一:查找路由器型号 首先,我们需要查找路由器的型号。通常,型号信息可以在路由器的外壳上或者设备的背面找到。型号信息通常以字母和数字的组合形式呈现,例如\”RT-AC68U\”。 步骤二:查找…

    other 2023年8月1日
    00
  • 详解Python中while无限迭代循环方法

    详解Python中while无限迭代循环方法 在Python中,while循环是一种常用的迭代结构,它可以用于创建无限循环。在本攻略中,我们将详细讲解如何使用while循环来实现无限迭代,并提供两个示例说明。 1. 基本语法 while循环的基本语法如下: while condition: # 循环体 其中,condition是一个布尔表达式,当其值为Tru…

    other 2023年7月28日
    00
  • vs2010打包安装包带数据库

    VS2010打包安装包带数据库 在软件开发过程中,经常需要将开发完成的程序打包成安装包进行发布。为了方便用户的安装,可以将程序的依赖项也打包进去,比如数据库。本文将介绍如何使用VS2010打包安装包并将数据库一起打包。 准备工作 在开始之前,需要安装VS2010和SQL Server 2008 R2(假设你的程序是基于该版本的数据库开发的)。同时,需要确保你…

    其他 2023年3月28日
    00
  • Shell全局变量、局部变量与特殊变量的具体使用

    Shell全局变量、局部变量与特殊变量的具体使用 在Shell中,变量的使用非常重要,特别是各种变量的使用方式。本篇文章将详细讲解Shell中的全局变量、局部变量与特殊变量,并给出一些示例说明。 全局变量 全局变量在整个程序运行时都是可用的,可以被所有函数或命令使用。在Shell中,定义全局变量不需要显示声明,直接赋值即可。例如: #!/bin/bash g…

    other 2023年6月27日
    00
  • p2s、p2p、p2sp之对比

    p2s、p2p、p2sp之对比 在互联网技术发展的过程中,点对点通信技术成为一种备受关注的技术之一。p2p、p2s、p2sp正是近年来应用最广泛的三种点对点技术。它们都可以实现快速的下载、数据传输等功能,但是它们之间也存在一定的差异与区别。 p2p技术 p2p技术是peer-to-peer(对等网络)的缩写,指的是两台计算机之间的通信方式。p2p基于一个分布…

    其他 2023年3月29日
    00
  • 浅谈一下JVM垃圾回收算法

    浅谈一下JVM垃圾回收算法 简介 JVM(Java虚拟机)是Java程序的运行环境,其中的垃圾回收算法是JVM的核心组成部分。垃圾回收算法的目标是自动管理内存,释放不再使用的对象,以避免内存泄漏和提高程序性能。本文将介绍几种常见的JVM垃圾回收算法,并提供示例说明。 1. 标记-清除算法(Mark and Sweep) 标记-清除算法是最基本的垃圾回收算法之…

    other 2023年8月2日
    00
  • 鼠标双击无法打开文件夹的三种解决办法

    那我来为你讲解“鼠标双击无法打开文件夹的三种解决办法”的完整攻略。 问题描述 我们在使用电脑时,有时会出现鼠标双击无法打开文件夹的情况,这种情况通常会给我们的工作和生活带来一定的困扰。接下来,我们将介绍三种解决这种问题的方法。 方法一:修复注册表 这是最常见的解决方案之一,但在进行此方法之前,我们建议您先备份您的注册表。具体操作方法是,按Windows+R键…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部