所有包含IM功能的App(如微信, 微博, QQ, 支付宝等)都提供了Emoji表情之类的虚拟键盘, 如下图:
本文只着重介绍如何实现输入法键盘和自定义虚拟键盘的流畅切换, 而不介绍如何实现虚拟键盘, 因为后者实现相对容易, 而前者若实现不好, 则会出现体验的问题, 比如输入区域的视图在切换时会跳动等问题.
知识要点:
- AndroidManifest.xml: activity属性 android:windowSoftInputMode
- InputMethodManager
- Window 管理机制
- View 管理机制
基本思路:
- 假设最外层视图为LinearLayout
- 虚拟键盘以layout形式直接添加到页面layout-xml中, 进入上述图中页面时, 默认是隐藏该虚拟键盘布局的, 输入法键盘也是默认收起的
- 虚拟键盘高度应该为输入法键盘的高度, 因此, 输入法弹出时需要保存其高度值, 另外, 如果弹出虚拟键盘前未弹出过输入法键盘, 那么这时是不知道其高度值的, 因此需要预设一个高度值
- 在切换键盘时, 动态调整内容区域(如聊天内容列表)的高度, 当虚拟键盘弹出时, 设置内容区域的高度为固定高度值, 而当虚拟键盘隐藏时, 还原内容区域的高度, 这样就可以实现键盘间的流畅切换了
实现代码:
具体用法:
> 页面布局
<?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> <FrameLayout android:id="@+id/emoji_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:background="#aaa" android:minHeight="200dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Hello, Emoji!" /> </FrameLayout> </LinearLayout>
layout-xml: activity_main.xml
> 页面代码
public class MainActivity extends AppCompatActivity implements View.OnTouchListener, View.OnClickListener { private ListView mListView; private EditText mEditText; private ImageView mEmojiImage; private View mEmojiLayout; 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); mEmojiLayout = findViewById(R.id.emoji_layout); mVirtualKeyboardController = new VirtualKeyboardController(this); mSoftKeyboardCompat = new SoftKeyboardCompat(this); mLayoutManager = new LinearLayoutManager(this, mSoftKeyboardCompat); mLayoutManager.setContentView(mListView); mLayoutManager.setSoftInputFocusView(mEditText); mLayoutManager.setEmojiKeyboardView(mEmojiLayout); mVirtualKeyboardController.setLayoutManager(mLayoutManager); } // 略, 详见github ... }
扩展用法:
如果页面布局的最外层视图不是LinearLayout, 扩展 VirtualKeyboardController.LayoutManager 接口即可, 可参考 LinearLayoutManager 实现代码.
相关:
END.
时间: 2024-11-04 19:37:55