Android View 完美实现EditText 在软键盘上边的示例
程序员文章站
2023-12-15 19:06:16
此方法基于popupwindow,适合需要回复内容时响应点击事件,打开软键盘,编辑框在软键盘上部。
优点,编辑框使用cleanedittext,监听输入状态来更改回复按钮...
此方法基于popupwindow,适合需要回复内容时响应点击事件,打开软键盘,编辑框在软键盘上部。
优点,编辑框使用cleanedittext,监听输入状态来更改回复按钮颜色,添加title等。
先展示效果
点击评论打开软键盘,编辑框在软键盘上部,点击其他区域消失收起软键盘:
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 及圆角背景就不展示了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。