所有包含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. DoraCMS 源码知识点备注

    项目需要研究了下DoraCMS这款开源CMS,真心做的不错:).用的框架是常用的express 4 + mongoose,代码也很规范,值得学习. 源码中一些涉及到的小知识点备注下: https:// ...

  2. ABP源码分析十二:本地化

    本文逐个分析ABP中涉及到locaization的接口和类,以及相互之间的关系.本地化主要涉及两个方面:一个是语言(Language)的管理,这部分相对简单.另一个是语言对应得本地化资源(Locali ...

  3. C#制作、打包、签名、发布Activex全过程

    一.前言 最近有这样一个需求,需要在网页上面启动客户端的软件,软件之间的通信.调用,单单依靠HTML是无法实现了,因此必须借用Activex来实现.由于本人主要擅长C#,自然本文给出了用C#实现的范例 ...

  4. How to debug .NET Core RC2 app with Visual Studio Code on Windows?

    Simone Chiaretta (http://codeclimber.net.nz/archive/2016/05/20/How-to-debug-NET-Core-RC2-app-with-Vi ...

  5. Chrome浏览器必装的扩展工具

    名称 作用 下载地址 Postman 模拟各种http请求 点击下载 JSON Viewer 访问json结果自动视图化 点击下载 Axure RP Extension for Chrome 查看Ax ...

  6. 记2016腾讯 TST 校招面试经历,电面、笔试写代码、技术面、hr面,共5轮

    (出处:http://www.cnblogs.com/linguanh/) 前序: 距离  2016 腾讯 TST 校招面试结束已经5天了,3月27日至今,目前还在等待消息.从投简历到两轮电面,再到被 ...

  7. Android 中关于static的使用问题

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5251564.html 项目中,在不停地接收串口数据很长一段时间(几小时)后,会偶然性的报错.初步排除了oom ...

  8. spring帝国-开篇

    spring简介: spring是一个开源框架,spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Dev ...

  9. 记录软件工程课程项目开发时遇到的各种小问题(django)

    1.python manage.py makemigrations 无效/无法检测出model的变化 在修改了models.py之后,我们想要更新数据库的表,使用了python manage.py m ...

  10. asp.net MVC 应用程序的生命周期

    下面这篇文章总结了 asp.net MVC 框架程序的生命周期.觉得写得不错,故转载一下. 转载自:http://www.cnblogs.com/yplong/p/5582576.html       ...