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

Android View 完美实现EditText 在软键盘上边的示例

程序员文章站 2023-12-05 18:41:10
此方法基于popupwindow,适合需要回复内容时响应点击事件,打开软键盘,编辑框在软键盘上部。 优点,编辑框使用cleanedittext,监听输入状态来更改回复按钮...

此方法基于popupwindow,适合需要回复内容时响应点击事件,打开软键盘,编辑框在软键盘上部。
优点,编辑框使用cleanedittext,监听输入状态来更改回复按钮颜色,添加title等。

先展示效果

点击评论打开软键盘,编辑框在软键盘上部,点击其他区域消失收起软键盘:

Android View 完美实现EditText 在软键盘上边的示例

Android View 完美实现EditText 在软键盘上边的示例

1.baseselectpopupwindow 的代码。

public class baseselectpopupwindow extends popupwindow {

private view popview;

private view view;


private onheadclicklistener onheadclicklistener;


private textview tv_head;


protected context context;


private boolean isopenkeyboard=false;;


private boolean isshowtitle=true;

private boolean isokclose=true;


protected int maxtextsize = 24;
protected int mintextsize = 14;
public baseselectpopupwindow(context context, int layoutid ) {

  this.context=context;
  layoutinflater inflater = (layoutinflater) context
      .getsystemservice(context.layout_inflater_service);
  popview = inflater.inflate(r.layout.pop_view, null);
  tv_head=(textview) popview.findviewbyid(r.id.tv_head);

  linearlayout contentview = (linearlayout) popview
      .findviewbyid(r.id.content);
  view=inflater.inflate(layoutid, null);
  contentview.addview(view,contentview.getlayoutparams());
  // btn_take_photo.setonclicklistener(itemsonclick);
  // 设置selectpicpopupwindow的view
  this.setcontentview(popview);
  // 设置selectpicpopupwindow弹出窗体的宽
  this.setwidth(layoutparams.fill_parent);
  // 设置selectpicpopupwindow弹出窗体的高

  windowmanager wm = (windowmanager) context
      .getsystemservice(context.window_service);
//  this.setheight(wm.getdefaultdisplay().getheight() / 2);
  this.setheight(layoutparams.wrap_content);
  // 设置selectpicpopupwindow弹出窗体可点击
  this.setfocusable(true);
  // 设置selectpicpopupwindow弹出窗体动画效果
  this.setanimationstyle(r.style.animbottom);
  // 实例化一个colordrawable颜色为半透明
  colordrawable dw = new colordrawable(0xb0000000);
  // 设置selectpicpopupwindow弹出窗体的背景
  this.setbackgrounddrawable(dw);
  // mmenuview添加ontouchlistener监听判断获取触屏位置如果在选择框外面则销毁弹出框

  /*
   * popview.setontouchlistener(new ontouchlistener() {
   * 
   * public boolean ontouch(view v, motionevent event) {
   * 
   * int height = popview.findviewbyid(r.id.pop_layout).gettop(); int
   * y=(int) event.gety(); if(event.getaction()==motionevent.action_up){
   * if(y<height){ dismiss(); } } return true; } });
   */

  (popview.findviewbyid(r.id.btn_back)).setonclicklistener(new onclicklistener() {

    @override
    public void onclick(view v) {
       dismiss();
    }
  });

  (popview.findviewbyid(r.id.btn_right)).setonclicklistener(new onclicklistener() {

    @override
    public void onclick(view v) {
      if(onheadclicklistener!=null){
        onheadclicklistener.oklistener();
      }
      if(isokclose){
        dismiss();
      }

    }
  });

  if(isopenkeyboard){
    openkeyboard();
  }



}
public boolean isshowtitle() {
  return isshowtitle;
}
public void setshowtitle(boolean isshowtitle) {
  this.isshowtitle = isshowtitle;
  if(!isshowtitle){
    ((relativelayout)tv_head.getparent()).setvisibility(view.gone);
  }
}
/**
 * 打开软键盘
 */
private void openkeyboard() {

    timer timer = new timer();
    timer.schedule(new timertask() {
        @override
        public void run() {
            inputmethodmanager imm = (inputmethodmanager) context.getsystemservice(context.input_method_service);
            imm.togglesoftinput(0, inputmethodmanager.hide_not_always);

        }
    }, 1000);
}
public boolean isopenkeyboard() {
  return isopenkeyboard;
}
public void setopenkeyboard(boolean isopenkeyboard) {
  this.isopenkeyboard = isopenkeyboard;
}

public onheadclicklistener getonheadclicklistener() {
  return onheadclicklistener;
}

public void setonheadclicklistener(onheadclicklistener onheadclicklistener) {
  this.onheadclicklistener = onheadclicklistener;
}

public interface onheadclicklistener{
  public void oklistener();
}



public void settitle(string value){
  if(tv_head!=null){
    tv_head.settext(value);
  }
}
public boolean isokclose() {
  return isokclose;
}
public void setokclose(boolean isokclose) {
  this.isokclose = isokclose;
}
public context getcontext() {
  return context;
}

对应的xml 布局:

<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white_gray"
android:gravity="center_vertical" >

<relativelayout
  android:id="@+id/head"
  android:layout_width="match_parent"
  android:layout_height="44dp"
  android:layout_alignparenttop="true"
  android:background="@color/head_yellow" >

  <textview
    android:id="@+id/btn_back"
    style="@style/nav_side_title_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignparentleft="true"
    android:layout_centervertical="true"
    android:layout_marginleft="15dp"
    android:text="@string/cancel"
    android:textcolor="@color/black_light_color"
    android:textsize="@dimen/titletextsize" />

  <textview
    android:id="@+id/tv_head"
    style="@style/nav_head_title_text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:ellipsize="end"
    android:gravity="center"
    android:visibility="gone" />

  <textview
    android:id="@+id/btn_right"
    style="@style/nav_side_title_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignparentright="true"
    android:layout_centervertical="true"
    android:layout_marginright="15dp"
    android:text="@string/sure"
    android:textcolor="@color/black"
    android:textsize="@dimen/titletextsize" />
</relativelayout>

<linearlayout
  android:id="@+id/content"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_below="@id/head"
  android:gravity="center"
  android:orientation="vertical" >
 </linearlayout>

</relativelayout>

其中style:nav_side_title_text是定义文字大小的。

2.需要使用的时候

private baseselectpopupwindow popwiw;// 回复的 编辑框

声明之后使用的时候初始化并调用:

 private void popwiw( ) {

  popwiw = new baseselectpopupwindow(context, r.layout.edit_data);
  // popwiw.setopenkeyboard(true);
  popwiw.setinputmethodmode(popupwindow.input_method_needed);
  popwiw.setfocusable(true);
  popwiw.setsoftinputmode(windowmanager.layoutparams.soft_input_adjust_resize);
  popwiw.setshowtitle(false);
  inputmethodmanager im = (inputmethodmanager) context
      .getsystemservice(context.input_method_service);
  im.togglesoftinput(0, inputmethodmanager.hide_not_always);

  final button send = (button) popwiw.getcontentview().findviewbyid(
      r.id.btn_send);
  final edittext edt = (edittext) popwiw.getcontentview().findviewbyid(
      r.id.edt_content);

  edt.setinputtype(editorinfo.type_class_text);
  edt.setimeoptions(editorinfo.ime_action_send);
  edt.addtextchangedlistener(new textwatcher() {

    @override
    public void ontextchanged(charsequence s, int start, int before,
                 int count) {
      if (textutils.isempty(edt.gettext())) {
        send.setenabled(false);
      } else {
        send.setenabled(true);
      }
    }

    @override
    public void beforetextchanged(charsequence s, int start, int count,
                   int after) {

    }

    @override
    public void aftertextchanged(editable s) {
      // todo auto-generated method stub

    }
  });
  edt.setoneditoractionlistener(new textview.oneditoractionlistener() {

    @override
    public boolean oneditoraction(textview v, int actionid,
                   keyevent event) {
      if (actionid == editorinfo.ime_action_send
          || (event != null && event.getkeycode() == keyevent.keycode_enter)) {

        if (!textutils.isempty(edt.gettext().tostring().trim())) {
      string content = edt.gettext().tostring().trim();
          // /提交内容  sumbit(content)
          popwiw.dismiss();
        }
        return true;
      }
      return false;
    }
  });
  send.setonclicklistener(new view.onclicklistener() {

    @override
    public void onclick(view v) {
      if (!textutils.isempty(edt.gettext().tostring().trim())) {

        // /提交内容
        string content = edt.gettext().tostring().trim();

        popwiw.dismiss();
      }
    }
  });

  popwiw.settitle("回复" + nickname);
  popwiw.showatlocation(refreshlayout, gravity.bottom
      | gravity.center_horizontal, 0, 0);
}

对应的edit_data xml布局

<?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="55dp" >

<relativelayout
  android:layout_width="match_parent"
  android:layout_height="44dp"
  android:background="@drawable/bg_search"
  android:gravity="clip_vertical"
  android:orientation="vertical"
  android:paddingleft="12dp"
  android:paddingright="12dp" >

  <com.myapp.view.clearedittext
    android:id="@+id/edt_content"
    android:layout_width="match_parent"
    android:layout_height="55dp"
    android:layout_alignparentleft="true"
    android:layout_centervertical="true"
    android:layout_marginbottom="5dp"
    android:layout_marginright="65dp"
    android:layout_margintop="5dp"
    android:background="@drawable/edittext_back"
    android:focusable="true"
    android:hint="说点什么..."
    android:paddingleft="10dp"
    android:imeoptions="actionsend"
    android:paddingright="10dp"
    android:textcolor="@color/top_bg_shadow"
    android:textsize="@dimen/normaltextsize" >
  </com.myapp.view.clearedittext>

  <button
    android:id="@+id/btn_send"
    android:layout_width="60dp"
    android:layout_height="34dp"
    android:layout_alignparentright="true"
    android:layout_centervertical="true"
    android:background="@drawable/btn_send_rounded"
    android:enabled="false"
    android:paddingleft="12dp"
    android:paddingright="12dp"
    android:text="@string/send"
    android:textcolor="@color/white"
    android:textsize="@dimen/normaltextsize" />
</relativelayout>

</linearlayout>

对于clearedittext,应该都不陌生,

public class clearedittext extends edittext implements 
  onfocuschangelistener, textwatcher { 
/**
 * 删除按钮的引用
 */
private drawable mcleardrawable; 

public clearedittext(context context) { 
  this(context, null); 
} 

public clearedittext(context context, attributeset attrs) { 
  //这里构造方法也很重要,不加这个很多属性不能再xml里面定义
  this(context, attrs, android.r.attr.edittextstyle); 
} 

public clearedittext(context context, attributeset attrs, int defstyle) {
  super(context, attrs, defstyle);
  init();
}


private void init() { 
  //获取edittext的drawableright,假如没有设置我们就使用默认的图片
  mcleardrawable = getcompounddrawables()[2]; 
  if (mcleardrawable == null) { 
    mcleardrawable = getresources() 
        .getdrawable(r.drawable.icon_edit_del); 
  } 
  mcleardrawable.setbounds(0, 0, mcleardrawable.getintrinsicwidth(), mcleardrawable.getintrinsicheight()); 
  setcleariconvisible(false); 
  setonfocuschangelistener(this); 
  addtextchangedlistener(this); 
} 

/**
 * 因为我们不能直接给edittext设置点击事件,所以我们用记住我们按下的位置来模拟点击事件
 * 当我们按下的位置 在 edittext的宽度 - 图标到控件右边的间距 - 图标的宽度 和
 * edittext的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向没有考虑
 */
@override 
public boolean ontouchevent(motionevent event) { 
  if (getcompounddrawables()[2] != null) { 
    if (event.getaction() == motionevent.action_up) { 
      boolean touchable = event.getx() > (getwidth() 
          - getpaddingright() - mcleardrawable.getintrinsicwidth()) 
          && (event.getx() < ((getwidth() - getpaddingright())));
      if (touchable) { 
        this.settext(""); 
      } 
    } 
  } 

  return super.ontouchevent(event); 
} 

/**
 * 当clearedittext焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏
 */
@override 
public void onfocuschange(view v, boolean hasfocus) { 
  if (hasfocus) { 
    setcleariconvisible(gettext().length() > 0); 
  } else { 
    setcleariconvisible(false); 
  } 
} 


/**
 * 设置清除图标的显示与隐藏,调用setcompounddrawables为edittext绘制上去
 * @param visible
 */
protected void setcleariconvisible(boolean visible) { 
  drawable right = visible ? mcleardrawable : null; 
  setcompounddrawables(getcompounddrawables()[0], 
      getcompounddrawables()[1], right, getcompounddrawables()[3]); 
} 


/**
 * 当输入框里面内容发生变化的时候回调的方法
 */
@override 
public void ontextchanged(charsequence s, int start, int count, 
    int after) { 
  setcleariconvisible(s.length() > 0); 
} 

@override 
public void beforetextchanged(charsequence s, int start, int count, 
    int after) { 

} 

@override 
public void aftertextchanged(editable s) { 

} 


/**
 * 设置晃动动画
 */
public void setshakeanimation(){
  this.setanimation(shakeanimation(5));
}


/**
 * 晃动动画
 * @param counts 1秒钟晃动多少下
 * @return
 */
public static animation shakeanimation(int counts){
  animation translateanimation = new translateanimation(0, 10, 0, 0);
  translateanimation.setinterpolator(new cycleinterpolator(counts));
  translateanimation.setduration(1000);
  return translateanimation;
}
}

一些icon 及圆角背景就不展示了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。