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

yizhihongxing

让我来详细讲解一下“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日

相关文章

  • c++常用字符串分割方法

    C++常用字符串分割方法 在C++中,对于字符串分割的需求,有很多种方法可以实现。下面将介绍一些常用的方法。 方法一:使用istringstream 可以使用C++标准库中的istringstream类来实现字符串分割。istringstream类是保存输入流的一个类,单位操作是单词,而一个单词以空格作为分隔符。 代码实现如下: #include <i…

    其他 2023年3月29日
    00
  • WPF自定义MenuItem样式的实现方法

    下面就是WPF自定义MenuItem样式的实现方法的完整攻略。 一、自定义菜单项的样式 1.1 添加菜单项 在XAML文件中添加Menu控件,并在里面添加MenuItem。例如: <Menu> <MenuItem Header="文件"/> <MenuItem Header="编辑"/&g…

    other 2023年6月25日
    00
  • eclipse如何以指定jdk启动

    当然,我可以为您提供有关“Eclipse如何以指定JDK启动”的完整攻略,以下是详细说明: Eclipse如何以指定JDK启动 在Eclipse中,通过以下步骤以指定JDK启动: 打开Eclipse,选择“Window”菜单,然后选择“Preferences”选项。 在“Preferences”对话框中,选择Java” -> “Installed JR…

    other 2023年5月7日
    00
  • java实现table添加右键点击事件监听操作示例

    下面将为您详细讲解Java实现Table添加右键点击事件监听的完整攻略。 准备工作 在开始之前,您需要进行以下准备工作: 确保您已经熟悉Java语言,了解如何使用Swing进行图形化界面的开发。 在您的开发环境中安装好了Java开发工具包(JDK)以及集成开发环境(IDE)。 添加右键点击事件监听 下面的步骤将会详细讲解如何添加右键点击事件的监听。假设我们有…

    other 2023年6月27日
    00
  • Spring解决循环依赖问题及三级缓存的作用

    下面是对于“Spring解决循环依赖问题及三级缓存的作用”的详细讲解: 一、什么是循环依赖问题? 在Spring中循环依赖是指两个或多个Bean互相依赖而形成的闭环,这样的循环依赖问题会导致Bean不能正确地完成依赖注入过程,从而导致应用程序启动失败。在依赖注入时,如果两个Bean之间相互依赖,但它们两个都没在容器中加载完成,那么就会出现循环引用的问题。例如…

    other 2023年6月26日
    00
  • 最新QQ6.8体验版下载发布 版本号13530

    最新QQ6.8体验版下载发布攻略 版本号:13530 欢迎使用最新发布的QQ6.8体验版!本攻略将为您提供详细的下载和安装步骤,以及两个示例说明。 下载步骤 首先,访问QQ官方网站(https://www.qq.com)。 在网站首页,找到并点击“下载”按钮。 在下载页面,您将看到最新版本的QQ体验版(版本号:13530)。点击下载按钮开始下载安装程序。 安…

    other 2023年8月3日
    00
  • iptables基础命令详解

    当然,我很乐意为您提供有关iptables基础命令的详细攻略。以下是详细的步骤和两个示例: 1. 什么是iptables? iptables是一个Linux内核中的防火墙工具,它可以监控网络流量并根据预定义的规则来过滤、修改和重定向流量。iptables可以用于保护网络安全、限制网络访问、防止攻击等。 2. iptables基础命令 以下是iptables的…

    other 2023年5月6日
    00
  • Highchart基础教程-图表的主要组成

    下面是“Highchart基础教程-图表的主要组成的完整攻略”,包括图表的主要组成、使用方法、两个示例说明等方面。 图表的主要组成 Highchart是一个基于JavaScript的图表库,它可以用来创建各种类型的图表,包括线图、柱状图、饼图等。一个Highchart图表主要由以下几个组成部分: 标题:用于描述图表的主题或主要内容。 坐标轴:用于显示数据的坐…

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