Android开发案例 - 自定义虚拟键盘
所有包含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开发案例 - 自定义虚拟键盘的更多相关文章
- android开发(45) 自定义软键盘(输入法)
概述 在项目开发中遇到一个需求,”只要数字键盘的输入,仅仅有大写字母的输入,某些输入法总是会提示更新,弹出广告等“,使得我们需要自定义输入. 关联到的知识 KeyboardView 一个视图 ...
- 关于在android手机中腾讯、阿里产品不自定义虚拟键盘的想法
1,自定义虚拟键盘,影响用户体验.你每个用户的喜好不一样,都有自己心仪的一款输入法.腾讯或是阿里设计出来的输入法很难满足上亿用户的喜好,到时候又是一场口水战,再说了就是专业的输入法肯定要比应用里嵌套的 ...
- android开发之自定义组件
android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...
- AllJoyn+Android开发案例-android跨设备调用方法
AllJoyn+Android开发案例-android跨设备调用方法 项目须要涉及AllJoyn开源物联网框架.前面主要了解了一些AllJoyn主要的概念.像总线,总线附件,总线对象,总线接口这种概念 ...
- Android开发之自定义的ListView(UITableViewController)
Android开发中的ListView, 顾名方法思义,就是表视图.表示图在iOS开发中就是TableView.两者虽然名称不一样,但是其使用方法,使用场景以及该控件的功能都极为相似,都是用来展示大量 ...
- Android开发之自定义组件和接口回调
说到自定义控件不得不提的就是接口回调,在Android开发中接口回调用的还是蛮多的.在这篇博客开始的时候呢,我想聊一下iOS的自定义控件.在iOS中自定义控件的思路是继承自UIView, 在UIVie ...
- iOS开发之自定义表情键盘(组件封装与自动布局)
下面的东西是编写自定义的表情键盘,话不多说,开门见山吧!下面主要用到的知识有MVC, iOS开发中的自动布局,自定义组件的封装与使用,Block回调,CoreData的使用.有的小伙伴可能会问写一个自 ...
- Android开发之自定义局部导航菜单
如今,要实现导航功能方案有很多.比如: 1.用3.0+自带的Toolbar + Fragment导航. 2.用Tabhost实现导航.小弟学浅,就只用过这两种方案实现导航. 但是这两种方案都有一个很明 ...
- Android开发进阶——自定义View的使用及其原理探索
在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...
随机推荐
- 跨平台的 .NET 运行环境 Mono 3.2 新特性
Mono 3.2 发布了,对 Mono 3.0 和 2.10 版本的支持不再继续,而且这两个分支也不再提供 bug 修复更新. Mono 3.2 主要新特性: LLVM 更新到 3.2 版本,带来更多 ...
- .NET面试题系列[4] - C# 基础知识(2)
2 类型转换 面试出现频率:主要考察装箱和拆箱.对于有笔试题的场合也可能会考一些基本的类型转换是否合法. 重要程度:10/10 CLR最重要的特性之一就是类型安全性.在运行时,CLR总是知道一个对象是 ...
- 【腾讯Bugly干货分享】OCS——史上最疯狂的iOS动态化方案
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/zctwM2Wf8c6_sxT_0yZvXg 导语 在 ...
- [免费了] SailingEase .NET Resources Tool (.NET 多语言资源编辑器)
这是我2010年左右,写 Winform IDE (http://www.cnblogs.com/sheng_chao/p/4387249.html)项目时延伸出的一个小项目. 最初是以共享软件的形式 ...
- 触控的手牌—Cocos Creator
科普 Cocos Creator是触控最新一代游戏工具链的名称.如果不太清楚的,可以先看一些新闻. 新编辑器Cocos Creator发布: 对不起我来晚了! http://ol.tgbus.co ...
- CSharpGL(13)用GLSL实现点光源(point light)和平行光源(directional light)的漫反射(diffuse reflection)
CSharpGL(13)用GLSL实现点光源(point light)和平行光源(directional light)的漫反射(diffuse reflection) 2016-08-13 由于CSh ...
- Android-RecyclerView
众所周知,RecyclerView是Google公司推出的V7包中的一个重要的控件,非常方便,可以替代现有的ListView和Gridview等控件,它功能很强大,灵活性好,扩展性强,还自带VIewH ...
- Eclipse 使用技巧
1.Eclipse 格式化代码时不换行与自动换行 Eclipse 推荐的编码风格默认是80列换行.每次用Eclipse自带的Ctrl+shift+f格式化代码时,如果原来的一行代码大于80列,Ecli ...
- 1.Kali安装到移动硬盘或者U盘中~Linux系通用方法(包括Android)
0.1.保证这个服务必须启动(虚拟机服务最好都启动) 0.2.看看U盘接口类型是否对应 1.安装第一步 2.安装第二步,选择kali镜像 3.设置存放位置(上面的名字无所谓,最后不会用它的,虚拟机只是 ...
- ERROR 1010 (HY000): Error dropping database (can't rmdir './test/', errno: 17)
在删除数据库的时候报标题所示错误 mysql> drop database test; ERROR (HY000): Error dropping database (can't rmdir ' ...