键盘弹出监听和点击键盘完键盘收起

android中并没有暴露给我们监听键盘弹出和收起的方法,为了监听键盘我们只能来监听界面的高度变化,这个大前提是不会变的,以前的方法是自定义最外层的Layout,并在onLayout方法中进行判断,但这样的判断有的时候是不准确的。为此我想到通过监听DecorView的Layoutchange方法中,比较DecorView和屏幕真正高度的来判断键盘的状态。为了能有这个变化我们用了SOFT_INPUT_ADJUST_PAN这个属性,以前判断键盘弹出都将这里设置成了SOFT_INPUT_ADJUST_RESIZE这属性,但是这个属性在RecyclerView中很可能会造成挡住输入框的情况。这也是在项目中遇到的坑才有了这个想法。代码如下:

public class MainActivity extends AppCompatActivity {

    public static final int STATUS_SHOW = 201;
    public static final int STATUS_HIDE = 202;
    public static final int STATUS_CLICK_OTHER = 203;
    private static final DisplayMetrics displayMetrics = new DisplayMetrics();
    public String TGA= MainActivity.class.getName();
    private int KeyStatus;
    BaseAdapter adapter;
    private RecyclerView mRecycler;
    private Activity mContext;
    private boolean isFirst;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN
                | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
        setContentView(R.layout.activity_main);
        getWindowManager().getDefaultDisplay()
                .getMetrics(displayMetrics);
        mRecycler = (RecyclerView)findViewById(R.id.Recycler);
        mContext = this;
        ArrayList list = new ArrayList();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        list.add("6");

        adapter = new BaseAdapter(mContext);
        adapter.lists = list;
        mRecycler.setLayoutManager(new LinearLayoutManager(mContext));
        mRecycler.setAdapter(adapter);

        final int  tempheight =  displayMetrics.heightPixels  / 4;
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });


        getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                Rect rect = new Rect();
                getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
                if(bottom != 0 && oldBottom != 0 && bottom - rect.bottom <= 0 && KeyStatus != STATUS_HIDE) {
                    Toast.makeText(mContext,"键盘消失",Toast.LENGTH_SHORT).show();
                    Log.d(TGA,"键盘消失");
                    if(isFirst){
                        isFirst = false;
                        return;
                    }
                    KeyStatus = STATUS_HIDE;
                }else
                if(bottom!=0 && oldBottom!=0 && bottom - rect.bottom > tempheight && KeyStatus != STATUS_SHOW){
                    Toast.makeText(mContext,"弹出键盘",Toast.LENGTH_SHORT).show();
                    Log.d(TGA,"弹出键盘");
                    KeyStatus = STATUS_SHOW;
//                    isShowKey = true;
                }
            }
        });
    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();

            if (isShouldHideInput(v, ev) && KeyStatus != STATUS_HIDE) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    KeyStatus = STATUS_CLICK_OTHER;
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                    return false;
                }
            }
            return super.dispatchTouchEvent(ev);
        }
        // 必不可少,否则所有的组件都不会有TouchEvent了
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

    public boolean isShouldHideInput(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] leftTop = {0, 0};
            //获取输入框当前的location位置
            v.getLocationInWindow(leftTop);

            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + v.getHeight();
            int right = left + v.getWidth();
            if (event.getRawX() > left && event.getRawX() < right
                    && event.getRawY() > top && event.getRawY() < bottom) {
                // 点击的是输入框区域,保留点击EditText的事件
                Toast.makeText(mContext,"是editext",Toast.LENGTH_SHORT).show();
                Log.d(TGA,"是editext");
                return false;
            } else {
                return true;
            }
        }
        return false;
    }


}

为了实现点击键盘外面的区域收起键盘,一般都是重写dispatchTouchEvent来截取点击事件,在这里判读你所点击的View是不是一个edittext的这里要注意这里获取点击事件的位置时,一定要用getRawX和 getRawY这样才能获取正确的位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值