所有包含IM功能的App(如微信, 微博, QQ, 支付宝等)都提供了Emoji表情之类的虚拟键盘,  如下图:

  

本文只着重介绍如何实现输入法键盘和自定义虚拟键盘的流畅切换, 而不介绍如何实现虚拟键盘, 因为后者实现相对容易, 而前者若实现不好, 则会出现体验的问题, 比如输入区域的视图在切换时会跳动等问题.

知识要点:

  • AndroidManifest.xml: activity属性 android:windowSoftInputMode 
  • InputMethodManager
  • Window 管理机制
  • View 管理机制

基本思路:

  • 假设最外层视图为LinearLayout
  • 虚拟键盘以layout形式直接添加到页面layout-xml中, 进入上述图中页面时, 默认是隐藏该虚拟键盘布局的, 输入法键盘也是默认收起的
  • 虚拟键盘高度应该为输入法键盘的高度, 因此, 输入法弹出时需要保存其高度值, 另外, 如果弹出虚拟键盘前未弹出过输入法键盘, 那么这时是不知道其高度值的, 因此需要预设一个高度值
  • 在切换键盘时, 动态调整内容区域(如聊天内容列表)的高度, 当虚拟键盘弹出时, 设置内容区域的高度为固定高度值, 而当虚拟键盘隐藏时, 还原内容区域的高度, 这样就可以实现键盘间的流畅切换了

实现代码:

具体用法:

> 页面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/root_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <include
android:id="@+id/content"
layout="@layout/include_content" /> <include
android:id="@+id/vkb_layout"
layout="@layout/include_vkb" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> <ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0" /> <ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/divider_vertical" /> <LinearLayout
android:id="@android:id/inputArea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp"> <EditText
android:id="@android:id/input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:inputType="textMultiLine"
android:maxLines="4"> <requestFocus />
</EditText> <ImageView
android:id="@+id/emoji"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:contentDescription="@null"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
</LinearLayout>

include_content.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#aaa"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hello, Emoji!" />
</FrameLayout>

include_vkb.xml

> 页面代码

public class MainActivity extends AppCompatActivity
implements View.OnTouchListener, View.OnClickListener {
private static final String TAG = "MainActivity"; private ListView mListView;
private EditText mEditText;
private ImageView mEmojiImage; private View mVirtualKeyboardLayout; private VirtualKeyboardController mVirtualKeyboardController;
private LayoutManager mLayoutManager;
private SoftKeyboardCompat mSoftKeyboardCompat; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mListView = (ListView) findViewById(android.R.id.list);
mListView.setOnTouchListener(this);
initListAdapter(); mEditText = (EditText) findViewById(android.R.id.input);
mEditText.setOnClickListener(this); mEmojiImage = (ImageView) findViewById(R.id.emoji);
mEmojiImage.setOnClickListener(this); mVirtualKeyboardLayout = findViewById(R.id.vkb_layout); mVirtualKeyboardController = new VirtualKeyboardController(this);
mSoftKeyboardCompat = new SoftKeyboardCompat(this);
mLayoutManager = new LinearLayoutManager(this, mSoftKeyboardCompat);
mLayoutManager.setAnchorView(findViewById(R.id.content));
mLayoutManager.setSoftInputFocusView(mEditText);
mLayoutManager.setVirtualKeyboardView(mVirtualKeyboardLayout);
mVirtualKeyboardController.setLayoutManager(mLayoutManager);
} ...
}

扩展用法:

如果页面布局的最外层视图不是LinearLayout, 扩展 VirtualKeyboardController.LayoutManager 接口即可, 可参考 LinearLayoutManager 实现代码.

相关:

END.

Android开发案例 - 自定义虚拟键盘的更多相关文章

  1. android开发(45) 自定义软键盘(输入法)

    概述 在项目开发中遇到一个需求,”只要数字键盘的输入,仅仅有大写字母的输入,某些输入法总是会提示更新,弹出广告等“,使得我们需要自定义输入. 关联到的知识 KeyboardView      一个视图 ...

  2. 关于在android手机中腾讯、阿里产品不自定义虚拟键盘的想法

    1,自定义虚拟键盘,影响用户体验.你每个用户的喜好不一样,都有自己心仪的一款输入法.腾讯或是阿里设计出来的输入法很难满足上亿用户的喜好,到时候又是一场口水战,再说了就是专业的输入法肯定要比应用里嵌套的 ...

  3. android开发之自定义组件

    android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...

  4. AllJoyn+Android开发案例-android跨设备调用方法

    AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...

  5. Android开发之自定义的ListView(UITableViewController)

    Android开发中的ListView, 顾名方法思义,就是表视图.表示图在iOS开发中就是TableView.两者虽然名称不一样,但是其使用方法,使用场景以及该控件的功能都极为相似,都是用来展示大量 ...

  6. Android开发之自定义组件和接口回调

    说到自定义控件不得不提的就是接口回调,在Android开发中接口回调用的还是蛮多的.在这篇博客开始的时候呢,我想聊一下iOS的自定义控件.在iOS中自定义控件的思路是继承自UIView, 在UIVie ...

  7. iOS开发之自定义表情键盘(组件封装与自动布局)

    下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...

  8. Android开发之自定义局部导航菜单

    如今,要实现导航功能方案有很多.比如: 1.用3.0+自带的Toolbar + Fragment导航. 2.用Tabhost实现导航.小弟学浅,就只用过这两种方案实现导航. 但是这两种方案都有一个很明 ...

  9. Android开发进阶——自定义View的使用及其原理探索

    在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...

随机推荐

  1. Linux学习日记-EF6的安装升级(三)

    在vs2013中使用EF是5的但是如果想使用 “来自数据库据的Code First” 这个生成模板就会发现 它会提示你EF的版本太低请升级 下面就是解决办法: 安装实体框架6 在工具菜单中,点击NuG ...

  2. JS模块化开发:使用SeaJs高效构建页面

    一.扯淡部分 很久很久以前,也就是刚开始接触前端的那会儿,脑袋里压根没有什么架构.重构.性能这些概念,天真地以为前端===好看的页面,甚至把js都划分到除了用来写一些美美的特效别无它用的阴暗角落里,就 ...

  3. 高级SQL运用

    一:什么是数据库设计? 数据库设计就是将数据库中的数据实体以及这些数据实体之间的关系,进行规范和结构化的过程. 二:为什么要实施数据库设计? 1:良好的数据库设计可以有效的解决数据冗余的问题 2:效率 ...

  4. 深入MySQL索引

    MySQL索引作为数据库优化的常用手段之一在项目优化中经常会被用到, 但是如何建立高效索引,有效的使用索引以及索引优化的背后到底是什么原理?这次我们深入数据库索引,从索引的数据结构开始说起. 索引原理 ...

  5. SQL Server-聚焦强制索引查询条件和Columnstore Index(九)

    前言 本节我们再来穿插讲讲索引知识,后续再讲数据类型中的日期类型,简短的内容,深入的理解,Always to review the basics. 强制索引查询条件 前面我们也讲了一点强制索引查询的知 ...

  6. 谈谈iOS Animation

    零.前言 这里没有太多的代码细节,只是探索iOS动画的基本概念,以及其抽象模型,数学基础等.我们学习一个知识的时候一般有两个部分,抽象部分和形象部分,抽象好比语言的语法,是规则,形象好比具体的句子,可 ...

  7. 使用MATLAB对图像处理的几种方法(上)

    实验一图像的滤波处理 一.实验目的 使用MATLAB处理图像,掌握均值滤波器和加权均值滤波器的使用,对比两种滤波器对图像处理结果及系统自带函数和自定义函数性能的比较,体会不同大小的掩模对图像细节的影响 ...

  8. 13.JAVA之GUI编程将程序打包jar

    jar基本命令: 目标:将下列MyMenuDemo.java代码打包成jar. 方法如下: 1.把java代码放到d:\myclass目录下. 2.按下快捷键ctrl+r,打开运行窗口,输入cmd后回 ...

  9. FFmpeg学习2:解码数据结构及函数总结

    在上一篇文章中,对FFmpeg的视频解码过程做了一个总结.由于才接触FFmpeg,还是挺陌生的,这里就解码过程再做一个总结. 本文的总结分为以下两个部分: 数据读取,主要关注在解码过程中所用到的FFm ...

  10. HTML基本元素(四)

    1.HTML框架 框架的作用就是把浏览器窗口划分成多个子窗口,而且每个子窗口都可以载入各自的HTML文档. *注意:html框架集与body同级,因此不能同时出现! 框架结构标签:<frames ...