所有包含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. Visual Studio 2015正式发布

    Windows 10 RTM正式版要7月29日发布,微软的另一个重磅软件Visual Studio 2015已经率先发布,今天如期放出了正式版本.Visual Studio 2015包括许多新功能和更 ...

  2. 探索c#之Async、Await剖析

    阅读目录: 基本介绍 基本原理剖析 内部实现剖析 重点注意的地方 总结 基本介绍 Async.Await是net4.x新增的异步编程方式,其目的是为了简化异步程序编写,和之前APM方式简单对比如下. ...

  3. PHP_VERSION_ID是如何定义的

    PHP_VERSION_ID是一个整数,表示当前PHP的版本,从php5.2.7版本开始使用的,比如50207表示5.2.7.和PHP版本相关的宏定义在文件 phpsrcdir/main/php_ve ...

  4. PHP 高级编程(1/5) - 编码规范及文档编写

    PHP 高级程序设计学习笔记20140612 软件开发中的一个重要环节就是文档编写.他可以帮助未来的程序维护人员和使用者理解你在开发时的思路.也便于日后重新查看代码时不至于无从下手.文档还有一个重要的 ...

  5. leetcode--5. Longest Palindromic Substring

    题目来自 https://leetcode.com/problems/longest-palindromic-substring/ 题目:Given a string S, find the long ...

  6. Hibernate(5)—— 联合主键 、一对一关联关系映射(xml和注解) 和 领域驱动设计

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to One 映射关系 一对一单向外键(XML/Annotation) 一对一双向外键关联(XML/A ...

  7. spring ioc

    spring ioc是spring的核心之一,也是spring体系的基础,那么spring ioc所依赖的底层技术是什么的?反射,以前我们开发程序的时候对象之间的相互调用需要用new来实现,现在所有的 ...

  8. 【Android】 修复ijkPlayer进行m3u8 hls流播放时seek进度条拖动不准确的问题

    项目中使用的播放器是ijkPlayer,发现播放切片特点的hls流(m3u8格式的视频)拖动seekBar的时候会莫名的跳转或者seek不到准确的位置,发现网友也遇到了同样的问题,ijk的开发者也说明 ...

  9. ASP.NET Core 中文文档 第二章 指南(4.10)检查自动生成的Detail方法和Delete方法

    原文 Examining the Details and Delete methods 作者 Rick Anderson 翻译 谢炀(Kiler) 校对 许登洋(Seay).姚阿勇(Mr.Yao) 打 ...

  10. 解决Asp.net Mvc中使用异步的时候HttpContext.Current为null的方法

    在项目中使用异步(async await)的时候发现一个现象,HttpContext.Current为null,导致一系列的问题. 上网查了一些资料后找到了一个对象: System.Threading ...