欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android编程之ListView和EditText发布帖子隐藏软键盘功能详解

程序员文章站 2023-11-12 12:28:52
本文实例讲述了android编程之listview和edittext发布帖子隐藏软键盘功能。分享给大家供大家参考,具体如下: 在android开发中,手动调用软件盘的隐藏...

本文实例讲述了android编程之listview和edittext发布帖子隐藏软键盘功能。分享给大家供大家参考,具体如下:

在android开发中,手动调用软件盘的隐藏和显示有时候也是非常常见的需求。

edittext控件实现了点击打开软键盘输入功能,but why ? 为什么edittext可以点击弹出keyboard,而textview却不可以,edittext继承textview做了哪些修改呢?关于这些问题得查看相关具体代码如何实现可以参考,看似简单的控件其实系统封装实现的很复杂。这里告诫和我一样一路自学android的开发者善于思考事件背后的本质,共勉。

开发有个布局是最外层是framelayout,包裹了listview,bottom底部是个edit输入框,当点输入框打开keyboard时候,需要下滑listview隐藏keyboard,但上滑继续滑动listview。

刚开始,我尝试了给listview设置clicklistener,设置onscrolllistener,重写它的ontouchevent方法,但是发现并不能达到自己满意的效果(发现code有段时间了,自己都有种修改代码不修改自己满意为止不罢休的纠结感)。

为什么不满意,因为每次listview滑动的时候调用hide keyboard会导致listview闪一下重影现象,因为listview正在滑动调用了hide keyboard,并且activity设置的是adjustresize会重新onlayout整个布局。(ps:之前也纠结过这个问题,adjustresize属性导致底部的edit没有跟着keyboard移动,而是等keyboard打开后edit在layout到合适的位置了。最后总结出的问题是需要调整布局,并且用adjustpan属性,相信类似微信聊天界面肯定也是这样做的,有更好的办法欢迎留言探讨!)

重新了最外层的framelayout的onintercepttouchevent拦截touch方法。直接贴代码了

@override
  public boolean onintercepttouchevent(motionevent ev) {
  //键盘开 && 第一个scroll dy》0
  if(showsoftinput) {
    if(mvelocitytracker == null) {
      mvelocitytracker = velocitytracker.obtain();
    }
    mvelocitytracker.addmovement(ev);
    switch (ev.getaction()) {
    case motionevent.action_down:
      downy = (int) ev.gety();
      showdispatchtouch = true;
      break;
    case motionevent.action_move:
      if(downy > ev.gety()) {
        showdispatchtouch = true;
      } else {
        showdispatchtouch = false;
        mvelocitytracker.computecurrentvelocity(1000);
        if(mvelocitytracker.getyvelocity() > 200 && mcontext instanceof activityreplydetail) {
          ((activityreplydetail)mcontext).hidesoftinput();
        }
      }
      break;
    default:
      break;
    }
  }
    return !showdispatchtouch || isanimating || super.onintercepttouchevent(ev);
  }

当然这里只有当keyboard弹出的时候才能拦截touch方法了,所以就要检测keyboard是否已弹出。如何检测

mreplyeditlayout.addonlayoutchangelistener(new onlayoutchangelistener() {
      @override
      public void onlayoutchange(view v, int left, int top, int right,
          int bottom, int oldleft, int oldtop, int oldright, int oldbottom) {
        if(!morientationchanged) {
          if(top > oldtop) {
            if(!medittouchedflag)
            setrequestedorientation(activityinfo.screen_orientation_full_sensor);
            //键盘隐藏
            msoftinputshow = false;
            mpulltonextlayout.setdispatchtouch(true);
            mpulltonextlayout.setisshowsoftinput(false);
          } else if (top < oldtop) {
            //键盘显示
            msoftinputshow = true;
            mpulltonextlayout.setisshowsoftinput(true);
          }
          medittouchedflag = false;
        }
      }
    });

onlayoutchangelistener监听到控件的layout的变化。view还有个监听getviewtreeobserver().addongloballayoutlistener(new ongloballayoutlistener()这个监听方法被调用的时机据我测试时在上面监听之后回调的。

这里还有实现横竖屏切换,横屏是点击输入框得先回到竖屏再弹出keyboard,就用到了上面两个listener,还有个onconfigurationchanged。

so当一步步根据自己的调试终于达到自己的满意了。

edittext收起keyboard其实更简单,直接重写ontouchevent

@override
public boolean ontouchevent(motionevent event) {
    if(msoftinputshow) {
      switch (event.getaction()) {
      case motionevent.action_cancel:
      case motionevent.action_up:
        imm.hidesoftinputfromwindow(getwindowtoken(), inputmethodmanager.hide_not_always);
        return true;
      }
    }
    return super.ontouchevent(event);
}
inputmethodmanager.hide_not_always

这个参数是告诉我们多次调用hidesoft不会一直调用,哈哈哈。

其实edit是个很高的edit,这种方法,会导致跟listview一样,edit在滑动时同时收起了keyboard导致重影,因为是adjustresize和布局的原因。

所以其实这里如果系统能给我们封装好方法,点击show keyboard,再点 hide keyboard并且不会滑动edit就好了,所以想修改代码,必须得了解edit为什么能实现点击show keyboard的功能。

更多关于android相关内容感兴趣的读者可查看本站专题:《android控件用法总结》、《android开发入门与进阶教程》、《android视图view技巧总结》、《android编程之activity操作技巧总结》、《android数据库操作技巧总结》及《android资源操作技巧汇总

希望本文所述对大家android程序设计有所帮助。