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日

相关文章

  • [工具推荐]001.flippdf使用教程

    [工具推荐]001.flippdf使用教程 什么是Flippdf? Flippdf是一种用于制作翻页效果电子书的工具,可以将PDF文件转换成具有翻页效果的电子书,适用于电子杂志、电子图书等多种场景。 如何使用Flippdf? 首先,需要下载并安装Flippdf软件,软件下载链接可以在官方网站获得。 安装完成后,打开软件,在首页可以选择“Import PDF”…

    其他 2023年3月29日
    00
  • mysql-8.0.11-winx64.zip安装教程详解

    MySQL-8.0.11-winx64.zip安装教程详解 下载MySQL安装包 首先,需要从MySQL官网 https://dev.mysql.com/downloads/mysql/ 下载适用于Windows系统的安装包。 选择需要下载的Windows版本之后,会进入到登录界面,输入MySQL账号密码进行登录后可下载对应版本的安装包。 解压安装包 将下载…

    other 2023年6月20日
    00
  • 手机WPS Office表格中的数据怎么自定义名称?

    若想在手机WPS Office表格中自定义数据的名称,可按照以下步骤进行: 点击表格中待自定义名称的数据单元格。 在弹出的编辑框中,点击“名称”选项卡。 在名称选项卡中,点击“定义名称”按钮。 在弹出的对话框中,输入该数据的自定义名称,可按照”名称”!图片或者”名称:范围”的格式定义,然后点击确定即可。 例如,我们要自定义名为“产品销量”的单元格,实现方式如…

    other 2023年6月25日
    00
  • 总结易语言MD5加密16位和32位方法

    总结易语言MD5加密16位和32位方法攻略 简介 MD5(Message Digest Algorithm 5)是一种常用的哈希算法,用于将任意长度的数据转换为固定长度的哈希值。在易语言中,我们可以使用MD5算法对字符串进行加密,得到16位或32位的MD5值。 16位MD5加密方法 以下是使用易语言实现16位MD5加密的方法: // 导入MD5模块 impo…

    other 2023年7月28日
    00
  • 在PHP中利用XML技术构造远程服务(下)

    下面是详细的攻略,分为两部分。 第一部分:准备工作 1. 安装xmlrpc扩展 要使用XML技术构建远程服务,需要在PHP中安装XMLRPC扩展。可以执行以下命令来安装扩展: sudo apt-get install php-xmlrpc 2. 编写服务端代码 PHP中的XML-RPC扩展提供了一个xmlrpc_server类,可以用于创建XML-RPC服务…

    other 2023年6月27日
    00
  • Java实现去重的方法详解

    Java实现去重的方法详解 什么是去重? 去重是指在一组数据中,将重复的数据剔除,仅保留一个或几个不重复的数据,以达到简化数据的目的。在数据处理和分析等场景中,去重是常见的操作。 去重的原理 根据数据结构和算法的知识,实现去重可以采用哈希表、二叉树、排序等方法。其中,哈希表在处理海量数据时效率较高,是一种常用的去重方法。 Java中去重的实现方法 方法一:利…

    other 2023年6月26日
    00
  • 跟我学Makefile(二)

    跟我学Makefile(二) 在上一篇跟我学Makefile中,我们学习了一些基础的Makefile语法和命令。在本文中,我们将继续深入了解如何使用Makefile自动化构建我们的代码。 变量 Makefile支持定义变量,可以提高代码的复用性和可维护性。变量可以用于定义命令、文件列表等。 变量的定义格式是变量名 = 值。例如: CC = gcc CFLAG…

    其他 2023年3月28日
    00
  • pycharm 使用anaconda为默认环境的操作

    要使用Anaconda为默认的Python环境,可以按照以下步骤操作: 步骤1:安装Anaconda 首先下载和安装Anaconda,可以从官网(https://www.anaconda.com/)下载安装包。 安装过程中需要勾选“Add Anaconda to my PATH environment variable”选项,这样Anaconda的路径就会被…

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