在做Android app时候有这样的业务场景:在评论页面,点击评论键弹起输入框,要求如下:1、点击,输入框获得焦点,键盘弹起。用户可以评论 2、修改手机键盘回车键为 发送
字样,用户输入完成以后点击发送,上传输入内容。弹出框消失,键盘消失。3、当输入框存在时候。点击外部区域,输入框消失。。如果此时键盘为弹出装太消失。4、如果键盘和输入框同时存在,点击手机返回按钮,键盘和输入框同时消失,而不是点击2次才全消失(这是个坑。正常情况下。点击返回键先消失键盘。再点击一次才消失输入框)。由于这些要求很多。网上很多相关介绍都是很多异常问题。。导致其中某一项不能成功。所以只能自己研究,捣鼓了一天。最后终于找到了好的解决办法。分享出来。首先看下效果图:
代码实现如下:首先是
一、主程序 MainActivity:
package cm.example.shurufademo;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements View.OnClickListener,MyEditText.BackListener
,OnGlobalLayoutListener{
EditText et;//点击弹出输入框的按钮。
PinglunorHuifuPopupwindow pinglunorHuifuPopupwindow;//点击以后弹出的输入框
InputMethodManager imm;//输入法控制器
View mroot;//当前MainActivity父布局
private boolean needHide = true;//控制popwindow消失 是否需要隐藏软键盘
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mroot=findViewById(R.id.mRoot);
et = (EditText) findViewById(R.id.et);
et.setOnClickListener(this);
mroot.getViewTreeObserver().addOnGlobalLayoutListener(this);
imm = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
}
/**
*
* @param 显示弹出框。
*/
private void showpinglunpop(View v){
pinglunorHuifuPopupwindow.showAtLocation(v, Gravity.BOTTOM, 0, 0); //设置layout在PopupWindow中显示的位置
backgroundAlpha(MainActivity.this,0.8f);
pinglunorHuifuPopupwindow.getEt_pinglun_dongtaixiangqing().setFocusable(true);
pinglunorHuifuPopupwindow.getEt_pinglun_dongtaixiangqing().requestFocus();
imm.toggleSoftInput(0,InputMethodManager.HIDE_NOT_ALWAYS);
}
/**
* 点击事件
*/
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.et:
if(null==pinglunorHuifuPopupwindow){
pinglunorHuifuPopupwindow=new PinglunorHuifuPopupwindow(MainActivity.this);
showpinglunpop(v);
pinglunorHuifuPopupwindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
backgroundAlpha(MainActivity.this,1.0f);
if (needHide){
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
}
});
pinglunorHuifuPopupwindow.getEt_pinglun_dongtaixiangqing().setOnKeyListener(new View.OnKeyListener() {
//这里是因为修改了输入法的回车键。这里模仿点击回车键向服务器提交数据,成功以后隐藏popwindow
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER
&& event.getAction() == KeyEvent.ACTION_DOWN) {
String content=pinglunorHuifuPopupwindow.getEt_pinglun_dongtaixiangqing().getText().toString().trim();
if(content.equals("")){
Toast.makeText(MainActivity.this,"总得输入点什么,再点击发送",Toast.LENGTH_LONG).show();
return true;
}else{
needHide=true;
if(pinglunorHuifuPopupwindow!=null&&pinglunorHuifuPopupwindow.isShowing()){
pinglunorHuifuPopupwindow.dismiss();
pinglunorHuifuPopupwindow=null;
}
Toast.makeText(MainActivity.this,"发布成功",Toast.LENGTH_LONG).show();
}
}
return false;
}
});
} else{
showpinglunpop(v);
}
break;
}
}
/**
*
* 通过监听父布局的高度。判断是否需要隐藏软键盘
*/
public void onGlobalLayout() {
if (mroot.getHeight() < getResources().getDisplayMetrics().heightPixels - 200) {
needHide = true;
}else{
needHide = false;
}
}
/**
*
* 解决当popwindow和输入法同时存在。。点击手机回退键。需要点击2次才能全消失。。此时一下就可以了
*/
@Override
public void back(TextView textView) {
if (pinglunorHuifuPopupwindow != null && pinglunorHuifuPopupwindow.isShowing()) {
pinglunorHuifuPopupwindow.dismiss();
}
}
/**
*
* 控制当前页面透明度。。就是遮罩。。没遮罩传1.0f,有遮罩<1.0f..当前用的是0.8f
*/
public static void backgroundAlpha(Activity act, float f) {
WindowManager.LayoutParams lp = act.getWindow().getAttributes();
lp.alpha = f;
act.getWindow().setAttributes(lp);
}
}
二、重写popwindow
package cm.example.shurufademo;
import android.graphics.drawable.BitmapDrawable;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
/**
* create by:sunlei on 2017/2/21 10:10
* e-mail:[email protected]
* introduce:点击首页的弹出框
*/
public class PinglunorHuifuPopupwindow extends PopupWindow {
MainActivity context;
RelativeLayout v;
private ImageView my_icon_popwindow;
private MyEditText et_pinglun_dongtaixiangqing;//弹出框的输入框,用自定义VIew主要是解决点击回退键不能让popwindow和输入法一起消失
public PinglunorHuifuPopupwindow(MainActivity c) {
this.context = c;
v = (RelativeLayout)context.getLayoutInflater().inflate(R.layout.pop_pinglunorhuifu, null);
et_pinglun_dongtaixiangqing=(MyEditText)v.findViewById(R.id.et_pinglun_dongtaixiangqing);
try {
et_pinglun_dongtaixiangqing.setBackListener((MyEditText.BackListener)context);
} catch (Exception e) {
e.printStackTrace();
}
show();
}
public void show() {
// 设置SelectPicPopupWindow弹出窗体的宽
this.setWidth(LayoutParams.MATCH_PARENT);
//this.setWidth(LayoutParams.WRAP_CONTENT);
// 设置SelectPicPopupWindow弹出窗体的高
this.setHeight(LayoutParams.WRAP_CONTENT);
// 设置SelectPicPopupWindow的View
this.setContentView(v);
//setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
// 设置SelectPicPopupWindow弹出窗体可点击
this.setFocusable(true);
this.setAnimationStyle(R.style.mypopwindow_anim_style);
this.setOutsideTouchable(true);
this.setBackgroundDrawable(new BitmapDrawable());
}
public EditText getEt_pinglun_dongtaixiangqing() {
return et_pinglun_dongtaixiangqing;
}
public void setEt_pinglun_dongtaixiangqing(MyEditText et_pinglun_dongtaixiangqing) {
this.et_pinglun_dongtaixiangqing = et_pinglun_dongtaixiangqing;
}
}
三 、重写EditText
package cm.example.shurufademo;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;
import android.widget.TextView;
/**
* create by:sunlei on 2017/4/14 11:06
* e-mail:[email protected]
* introduce:自定义Edittext
*/
public class MyEditText extends EditText {
public MyEditText(Context context) {
super(context);
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public interface BackListener {
void back(TextView textView);
}
private BackListener listener;
public void setBackListener(BackListener listener) {
this.listener = listener;
}
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (listener != null) {
listener.back(this);
}
}
return false;
}
}
四、定义MainActivity的配置文件为:
android:windowSoftInputMode="stateHidden|adjustResize" 必不可少
五、看不懂的可以下载源码:csdn Eclipse项目地址是下载请点击
或者复制 http://download.csdn.net/detail/a872822645/9824939
六、附带某些特殊情况。解决办法。
解决安卓全屏“FLAG_FULLSCREEN”状态下“adjustResize”失效,全屏状态下WebView的输入框被软键盘挡住的问题
http://blog.csdn.net/l_yinghao/article/details/46008863
解决windowSoftInputMode="adjustResize" 不生效
http://blog.163.com/ittfxin@126/blog/static/11067486320162210549679/