EditText监听输入完成和设置点击事件时与父控件的冲突问题

来源:互联网 发布:淘宝怎么编辑图文详情 编辑:程序博客网 时间:2024/05/21 07:04

最近在做项目时,发现一个问题,最后找到了解决办法,特在此记录一下,便于以后自己回忆以及和大家分享

问题描述:我在项目的页面B放了一个线性布局,里面有EditText,本意是从A页面跳转到B页面时,可能会先做别的操作,在修改EditText里面的内容(阐述一下:我是修改完EditText内容后,过几秒自动请求网络更改内容),但是当跳转到B页面时会弹出软键盘,这显然不好,最后在xml布局里面找到EditText的父控件(也就是线性布局)加了两个属性

android:focusable="true"android:focusableInTouchMode="true"

这样一来进入B页面后就不会加载软键盘

但是想修改EditText里面内容的时候发现一个问题,点击线性布局时会弹出软键盘,最后修改成功(这里采用了一个方法让点击线性布局时弹出软键盘并把焦点设置给EditText,写在代码① 里面),但是点击EditText时键盘是弹出来了,但是没有响应线性布局的点击事件,自然也就没修改成功,所以找了好多办法,最后采用分别监听线性布局的OnClickListener和EditText的OnTouchListener方法,分别设置相同的方法给两个监听,最后解决办法
(注:我发现EditText使用OnClickListener时有问题,因为EditText的setOnClickListener事件响应中,只有获取焦点的时候才会响应,如当焦点在别的控件上时,只能先点击获取焦点,第二次点击才会响应,解决办法改用setOnTouchListener监听)
一、先是线性布局的监听:
LinearLayout llname = findViewById(R.id.ll_name);
llname.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alterName();
}
});

二、再是EditText的监听
EditText etname = findViewById(R.id.et_name);
//设置etname的点击事件
etname.setOnTouchListener(new View.OnTouchListener() {
//按住和松开的标识
int touch_flag=0;
@Override
public boolean onTouch(View v, MotionEvent event) {
touch_flag++;
if(touch_flag==2){
alterName();
}
return false;
}
});

代码①
(描述:进入B页面后当点击线性布局时,弹出键盘,让线性布局下面的EditText获取焦点,然后当键盘弹出时,监听EditText的输入状态,当5秒内连续输入的时候移除上次的延时任务,5秒内不输入时,执行延时任务,我这里是请求网络,更改内容)

// 先弹出键盘,让焦点在输入框上alterName(){        etMyUsername.requestFocus();// 获取焦点        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);        imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);        if(imm.isActive()){            // 获取焦点,先设置光标遇到最后,然后监听输入框的动态变化            etMyUsername.setSelection(etMyUsername.length());            listenetMyUsername();        }    }    /**监听输入框的动态变化*/    private void listenetMyUsername() {        etMyUsername.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                if (delayRun != null) {                    //每次editText有变化的时候,则移除上次发出的延迟线程                    handler.removeCallbacks(delayRun);                }            }            @Override            public void afterTextChanged(Editable s) {                newName = s.toString();                //延迟5s,如果不再输入字符,则执行该线程的run方法,取消输入框的焦点                handler.postDelayed(delayRun, 2000);            }        });}/**     * 延迟线程,看是否还有下一个字符输入     */    private Runnable delayRun = new Runnable() {        @Override        public void run() {            //uploadName();       //这里写自己的逻辑        }    }; /**上传名字*/    private void uploadName() {        String url = Urls.Url_My_Name;        Map<String, String> params = new HashMap<>();        params.put("uid", uid);        params.put("name", newName);        OkHttpUtils.post()//                .url(url)//                .params(params)//                .build()//                .execute(new MyStringCallback2());    }    /**上传名字*/    class MyStringCallback2 extends StringCallback {        @Override        public void onError(Call call, Exception e) {            ToastUtils.showToast(mActivity, "网络有问题,请检查");        }        @Override        public void onResponse(String response) {            //System.out.println("PersonMsgActivity+界面修改用户名" + response);            MyAlterNameBean bean = new Gson().fromJson(response, MyAlterNameBean.class);            if (bean != null) {                int code = bean.code;                String msg = bean.msg;                if (code != 0) {                    ToastUtils.showToast(mActivity, msg);                }else {                    //ToastUtils.showToast(mActivity, "修改成功");                    // 每次更改成功后要通知我的界面也要改变显示内容                    Intent intent = new Intent();                    intent.putExtra(Keys.NEWNAME, newName);                    setResult(2, intent);                }            }        }    }
1 0