android 表情,软键盘冲突解决方案(仿微博等SNS应用)
之前总想搞一下这个模块,可是由于忙碌总是推迟,现在就把这块好好的弥补过来,下面是我实现的思路.本人才疏学浅,还望大家不要见笑。
首先我们还是先看写示例:
上面应用应该不用我过多介绍,下面我简单介绍下我如何实现的吧,想必这是大家最关心,前提说一点,思路上如果有不足的地方,或者有好的建议什么的,麻烦您多多指出,大家一起进步嘛.
首先我们从布局开始:
微博:红色方框我们称为底部导航栏,而蓝色部分是我们的表情窗口(包含表情分页点).
我的布局:或许大家看不到表情的布局,这是以因为我让她gone了.他就在底部导航栏的下面.
下面是表情布局代码:ViewPager添加表情GridView.(这里我用的是相对布局.或者FrameLayout,只是为了UE效果好一点.)
<RelativeLayout android:id="@+id/rlayout_emoji" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/note_toolbar_bg" android:orientation="vertical" android:visibility="gone" > <android.support.v4.view.ViewPager android:id="@+id/vp_emoji" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/layout_point" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:gravity="center" android:orientation="horizontal" android:padding="10dip" > </LinearLayout> </RelativeLayout>
Trouble 1: 有经验的朋友都知道, ViewPager这个布局中的wrap_content自适应是不起作用的.
我google了好久,也没有找到相关的解决方案,大部分都是写死(这点肯定是不允许的),ViewPager的父亲是ViewGroup,之前也试着基于ViewGoup实现过ViewPager的效果,想自己搞一个控件,可是有点不愿敲那么多代码,最后一气之下:决定代码中动态算取表情框的高度,然后对表情框进行设置.反正高度变化频率不大.首先我们显示三行表情图标,加上之间的间距,可以算取ViewPager应占有的高度.然后我们还要算取分页点应占有的高度,二者加起来就是我们表情框最终占有的高度.这样我们就可以实现表情框的显示了,有段开发经验的朋友实现这个应该很简单的.(代码我就不贴了,方法比较笨拙.)
Trouble 2:软键盘隐藏和显示问题.
首先我们先来看些软键盘相关的解释.
针对软键盘,如果想让键盘覆盖我们视图控件.那么在AndroidManifest.xml中对该Activity加上android:windowSoftInputMode="adjustPan" 如果想让软键盘不覆盖我们的视图,我们应该加上android:windowSoftInputMode="stateVisible|adjustResize" 这样屏幕会上移动.
相关的SoftInputMode值:
stateUnspecified:软键盘的状态(是否它是隐藏或可见)没有被指定。系统将选择一个合适的状态或依赖于主题的设置。这个是为了软件盘行为默认的设置。
stateUnchanged:软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。
stateHidden:当用户选择该Activity时,软键盘被隐藏——也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。
stateAlwaysHidden:软键盘总是被隐藏的,当该Activity主窗口获取焦点时。
stateVisible:软键盘是可见的,当那个是正常合适的时(当用户导航到Activity主窗口时)。
stateAlwaysVisible:当用户选择这个Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。
adjustUnspecified:它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置。
adjustResize:该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间.
adjustPan:该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。
之前做项目用到软键盘的时候总是googele,找到了就copy+paste,也不理解究竟是Why.这次算是花点时间整理了下,希望下次可以自己搞定。有点跑题了,言归正传,如果你在配置文件中设置这些SoftInputMode应该都达不到理想的效果,这里我分析一下微博等应用的操作。
首先我跳转到了微博的发表页面,这个时候软键盘显示,并且软键盘没有遮挡控件,所以模式应该为stateVisible|adjustResize.而当我们点击表情头像的时候,软键盘隐藏,显示表情框(仔细操作下应该会发现,软键盘在隐藏的过程表情框直接都显示好了,用户体验很好.).在软件盘隐藏的时候模式应该是adjustPan.既然模式是动态改变的,那么在配置文件中就解决不了问题了,我们只有在代码中动态控件。
具体代码如下:
InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (rlayout_emoji.getVisibility() == View.VISIBLE) {
iv_note_emoticon
.setImageResource(R.drawable.btn_emoticon_selector);
rlayout_emoji.setVisibility(View.GONE);
getWindow()
.setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
// 打开软键盘
mInputMethodManager.showSoftInput(et_note,
InputMethodManager.SHOW_FORCED);
} else {
iv_note_emoticon
.setImageResource(R.drawable.btn_keyboard_selector);
rlayout_emoji.setVisibility(View.VISIBLE);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
// 隐藏软键盘
mInputMethodManager.hideSoftInputFromWindow(getCurrentFocus()
.getApplicationWindowToken(), 0);
}
代码我想就不用我解释了,实现起来很简单,只是我google了那么久都没有找到方案,最终还是自己无意中想到了。这样我们就做到和微博的效果一样了。
总之做应用要注重的就是用户体验,操作一下比较fashion的应用就可以看到,大公司与小公司的差别在哪里。
在这里我发一下牢骚,我呆过三家公司,可没有一家公司让我满意,别说流程了,连个像样的UI都做不到,总觉得公司是在敷衍移动产品,认为不就是一个UI吗,不就是一些UE操作吗,流程随便一划,设计随便一搞,最后随便找个web的前端工程师随便划几个Psd文件就开工了.你说这样开发出来的应用有用吗,用户会埋单吗。没有用户,老板你如何变现!!!所以想开发一款应用,不管是大是小,一定要用心,不牢骚了,鄙人已经辞去工作专心搞自己的项目,总之我的理念就是:UI+UE这是最近本的移动应用要求.
最后看一下实现的效果吧.(Demo版)
就说到这里,如有疑问请留言.