项目中需要做评论功能,在软键盘弹出后在其上方弹出自定义的view,看下效果:
原理很简单,软键盘上方就是一个自定义的PopuWindow,在弹出PopuWindow的代码中激活了软键盘,随即PopuWindow就被软键盘顶到了其上方,里面还给PopuWindow加入了显示 和消失的动画,另外实现了对软键盘显示和隐藏状态的监听,以及对其高度的测量,需要做些逻辑处理的话可以直接在里面写相关的代码就ok了,开始上代码。。。。
1.先看下MainActivity.Java中的代码:
[java] view plain copy public class MainActivity extends Activity implements OnClickListener { private Button bt; private Button btn_submit; private PopupWindow popupWindow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bt = (Button) findViewById(R.id.bt); bt.setOnClickListener(this); //注册软键盘的监听 SoftKeyBoardListener.setListener(MainActivity.this, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() { @Override public void keyBoardShow(int height) { Toast.makeText(MainActivity.this, "键盘显示 高度" + height, Toast.LENGTH_SHORT).show(); } @Override public void keyBoardHide(int height) { Toast.makeText(MainActivity.this, "键盘隐藏 高度" + height, Toast.LENGTH_SHORT).show(); if(popupWindow!=null){ popupWindow.dismiss(); } } }); } /** * show soft input */ private void popupInputMethodWindow() { new Thread() { @Override public void run() { super.run(); InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE); imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); } }.start(); // } /** * show comment popupwindow(弹出评论的popupWindow) */ private void showPopupCommnet(final int pid, final int type) {// pe表示是评论还是举报1.代表评论。2.代表举报 View view = LayoutInflater.from(MainActivity.this).inflate( R.layout.comment_popupwindow, null); final EditText inputComment = (EditText) view .findViewById(R.id.comment); btn_submit = (Button) view.findViewById(R.id.submit_comment); if (type == 1) { btn_submit.setText("评论"); inputComment.setHint("请输入评论"); } popupWindow = new PopupWindow(view, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true); popupWindow.setTouchable(true); popupWindow.setTouchInterceptor(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return false; } }); popupWindow.setFocusable(true); // 设置点击窗口外边窗口消失 popupWindow.setOutsideTouchable(true); popupWindow.setBackgroundDrawable(getResources().getDrawable( R.drawable.popuwindow_white_bg)); // 设置弹出窗体需要软键盘 popupWindow.setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED); // 再设置模式,和Activity的一样,覆盖,调整大小。 popupWindow .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0); ColorDrawable cd = new ColorDrawable(0x000000); popupWindow.setBackgroundDrawable(cd); WindowManager.LayoutParams params = getWindow().getAttributes(); params.alpha = 0.4f; getWindow().setAttributes(params); // 设置popWindow的显示和消失动画 popupWindow.setAnimationStyle(R.style.mypopwindow_anim_style); popupWindow.update(); popupInputMethodWindow(); popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { // 在dismiss中恢复透明度 public void onDismiss() { WindowManager.LayoutParams params = getWindow().getAttributes(); params.alpha = 1f; getWindow().setAttributes(params); } }); btn_submit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // btn_submit.setClickable(false); String comment1 = inputComment.getText().toString().trim(); if (comment1.length() <= 0) { if (type == 1) { Toast.makeText(MainActivity.this, "评论内容不能为空", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "有非法内容", Toast.LENGTH_SHORT).show(); } return; } String comment2 = null; try { comment2 = URLEncoder.encode(comment1, "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } final String finalComment = comment2; popupWindow.dismiss(); Toast.makeText(MainActivity.this, finalComment, Toast.LENGTH_SHORT).show(); // 提交评论 // submitComment(finalComment, pid); } }); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.bt: showPopupCommnet(1, 1); break; default: break; } } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); if(popupWindow!=null){ popupWindow.dismiss(); } } }上面的代码中用到了一个对软键盘显示还是隐藏的监听类SoftKeyBoardListener,代码如下: [java] view plain copy public class SoftKeyBoardListener { private View rootView;//activity的根视图 int rootViewVisibleHeight;//纪录根视图的显示高度 private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener; public SoftKeyBoardListener(Activity activity) { //获取activity的根视图 rootView = activity.getWindow().getDecorView(); //监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变 rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //获取当前根视图在屏幕上显示的大小 Rect r = new Rect(); rootView.getWindowVisibleDisplayFrame(r); int visibleHeight = r.height(); if (rootViewVisibleHeight == 0) { rootViewVisibleHeight = visibleHeight; return; } //根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变 if (rootViewVisibleHeight == visibleHeight) { return; } //根视图显示高度变小超过200,可以看作软键盘显示了 if (rootViewVisibleHeight - visibleHeight > 200) { if (onSoftKeyBoardChangeListener != null) { onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight); } rootViewVisibleHeight = visibleHeight; return; } //根视图显示高度变大超过200,可以看作软键盘隐藏了 if (visibleHeight - rootViewVisibleHeight > 200) { if (onSoftKeyBoardChangeListener != null) { onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight); } rootViewVisibleHeight = visibleHeight; return; } } }); } private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) { this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener; } public interface OnSoftKeyBoardChangeListener { void keyBoardShow(int height); void keyBoardHide(int height); } public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) { SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity); softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener); } } 至于PopuWindow的布局comment_popupwindow.xml很简单,也一块贴上了 [java] view plain copy <?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:gravity="center_vertical" android:orientation="horizontal" > <Button android:layout_width="35dp" android:layout_height="40dp" android:background="@drawable/bt_circle_gray_bg" android:text="X"/> <EditText android:id="@+id/comment" android:layout_width="match_parent" android:layout_weight="1" android:background="@drawable/bt_square_yellow_bg" android:layout_height="40dp" /> <Button android:id="@+id/submit_comment" android:layout_width="70dp" android:layout_height="40dp" android:background="@drawable/bt_circle_gray_bg" android:text="提交" /> </LinearLayout>
还有PopuWindow显示和隐藏的动画:
隐藏时的动画pophiden_anim.xml
[java] view plain copy <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromYDelta="0" android:toYDelta="50%p" /> <alpha android:duration="500" android:fromAlpha="1.0" android:toAlpha="0.0" /> </set> 显示时的动画popshow_anim.xml [java] view plain copy <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="500" android:fromYDelta="100%p" android:toYDelta="0" /> <alpha android:duration="1000" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>
最后在styles.xml中进行一下配置就ok了:
[java] view plain copy <!-- 控制popuWindow显示和隐藏 --> <!-- 这个是加入的代码 --> <style name="mypopwindow_anim_style"> <item name="android:windowEnterAnimation">@anim/popshow_anim</item> <!-- 指定显示的动画xml --> <item name="android:windowExitAnimation">@anim/pophiden_anim</item> <!-- 指定消失的动画xml --> </style>